logo
bars
///
reCAPTCHA validation failed:原因与修复方法(2026)
Vladlen Vlasov
Vladlen Vlasov
技术撰稿人
November 3, 2026
4 分钟
请查看本网站所提供内容的使用条款。

reCAPTCHA validation failed:常见原因与修复方法

当网站无法确认表单是否由真人提交时,就可能显示 “reCAPTCHA validation failed”,并拒绝此次提交。无论你勾选了“我不是机器人”,还是 reCAPTCHA 在后台完成了无感验证,都可能出现这种情况。Google 返回了验证失败的结果,表单也就无法继续提交。

如果你只是想注册或登录,原因通常出在本地环境,例如广告拦截器干扰,或页面打开太久。如果是你自己的网站无法通过 reCAPTCHA 验证,则更可能是 reCAPTCHA 配置或表单代码有问题。

robots
立即开始自动化您的工作流 reCAPTCHA v2

要点速览

  • 服务器返回的错误码通常能说明原因,先查看错误码。如果没有错误码,依次检查 secret key、域名列表,以及 token 的生成时间。
  • token 只有两分钟有效期,而且 Google 只允许验证一次。使用 v3 时,应在访客点击 Submit 时调用 execute(),而不是在页面加载时调用。
  • 如果验证组件没有显示,检查广告拦截器、CSP 规则和防火墙。
  • “captcha score is not above the threshold” 与网站或插件设置的 threshold 有关,并不是 Google 设置了这个阈值。
  • Enterprise assessment 能更详细地解释 token 验证失败的原因。siteverify 将过期和重复使用的 token 统一归为 timeout-or-duplicate,而 Enterprise 分别使用 EXPIRED 和 DUPE。

reCAPTCHA validation failed 是什么意思?

验证流程在某个环节出了问题,可能是访客的浏览器,也可能是你的网站服务器。访客看到的报错可能相同,但排查位置并不一样。

客户端故障:组件未加载,或未通过验证挑战

如果问题出在浏览器,token 就不会生成。可能是组件根本没有加载,这也是用户说 reCAPTCHA 无法使用时最常见的情况;也可能是访客未能通过图片验证。两种情况下,后端都拿不到 token:请求要么没有发出,要么携带的 g-recaptcha-response 字段为空。Invisible reCAPTCHA 更难排查,因为页面上没有复选框,访客不容易察觉验证出了问题。如果没有适当的错误处理,表单看起来就像没有响应。

服务器端故障:success: false 和错误码

如果表单显示笼统的 “Error verifying reCAPTCHA”,token 很可能已经从浏览器发出,但 Google 在服务器提交验证后拒绝了它。具体原因可以从 siteverify 的响应中查看:

{
  "success": false,
  "error-codes": ["timeout-or-duplicate"]
}

基于 score 的密钥也可能返回 success: true,但 score 低于网站设置的 threshold。这时,拒绝请求的是你的网站代码,而不是 Google。

	终端中的 reCAPTCHA validation failed 错误与 SiteVerify API 响应
终端中显示的 reCAPTCHA SiteVerify API 错误响应

基本概念:site key、secret key、token、score 和 threshold

Site key(站点密钥)。密钥对中的公开部分,可以在页面的 HTML 或 JavaScript 中看到。

Secret key(私密密钥)。密钥对中的私密部分,只应由后端发送给 siteverify。在 Google Cloud 中,它标为 “legacy secret key”。

Token(令牌)。reCAPTCHA 完成验证后返回的字符串,在 v2 中通过 g-recaptcha-response 传递。Google 仅在两分钟内接受该 token,而且只允许验证一次。

Score(评分)。v3 和基于评分的 Enterprise 密钥返回的数值,范围为 0.0 到 1.0。分数越高,风险越低。

Threshold(阈值)。网站接受的最低 score,由你设置,而不是由 Google 替你决定。

reCAPTCHA 错误码速查

错误码来自 Google 的 siteverify 响应或 Enterprise assessment。因 score 过低而拒绝请求,则是你自己的阈值判断逻辑产生的结果。

错误码或现象出现位置原因修复方法
missing-input-secretsiteverify未发送 secret 参数检查 secret key 是否正确加载
invalid-input-secretsiteverifysecret key 错误,或误填了 site key使用与 site key 配套的 secret key
missing-input-responsesiteverify未发送 token,或防火墙规则移除了该字段确认 g-recaptcha-response 能传到后端
invalid-input-responsesiteverifytoken 格式错误、被截断,或由其他 site key 生成原样传递 token,不做修改
bad-requestsiteverifyGoogle 无法解析请求通过 POST 请求,以表单字段形式发送 secret 和 response
timeout-or-duplicatesiteverifytoken 已生成超过两分钟,或已经验证过在提交时获取 token,并且只验证一次
browser-error(Enterprise 中为 BROWSER_ERROR)仅出现在 Enterprise 的 invalidReason 中可重试的浏览器错误,例如网络故障再次调用 execute(),然后检查拦截器、CSP 和网络
v3 score 低于网站设置的 thresholdv3 的 score 或 Enterprise 的 riskAnalysis.score评分未达到设定阈值根据真实流量调整 threshold
success: true,但 hostname 不正确siteverify域名验证已关闭,token 来自其他网站启用域名验证,或在代码中检查 hostname

reCAPTCHA 为什么验证失败?常见原因

修复方法取决于具体原因。最常见的有四类:token 过期或重复使用,密钥与域名不匹配,组件无法加载,以及 score 低于网站设置的 threshold。

Token 过期或重复使用:timeout-or-duplicate

timeout-or-duplicate 表示 token 已生成超过两分钟,或已经验证过。根据 Google 的 SiteVerify 文档,每个 reCAPTCHA 用户响应 token 的有效期为两分钟,而且只能验证一次,以防止重放攻击。

  • 表单较长时,访客可能先勾选复选框,再花五分钟填写其他内容。在 v2 中,可以添加 data-expired-callback,提示访客重新勾选。
  • 如果结账页面在加载时就请求 v3 token,而买家花了三分钟填写银行卡信息,提交的 token 就已经过期。Google 建议在用户提交表单时执行验证,而不是提前生成 token。
  • 双击 Submit,或 JavaScript 处理函数与原生 submit 事件同时触发,都可能让表单向服务器提交两次。应在第一次点击后禁用按钮,仅在请求失败时重新启用。
  • 重复验证也可能发生在后端:中间件先验证 token,控制器随后又将同一 token 发给 siteverify。每个请求中的 token 只应验证一次。
  • 表单报错后,下次提交可能仍携带旧 token。在 v2 中调用 grecaptcha.reset();在 v3 中请求新的 token。

下面的 v3 示例在提交时获取 token,并禁用按钮,防止重复提交。

<form id="signup" action="/signup" method="POST">
  <!-- form fields -->
  <input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response">
  <button type="submit" id="submit-btn">Sign up</button>
</form>

<script src="https://www.google.com/recaptcha/api.js?render=YOUR_SITE_KEY"></script>
<script>
  const form = document.getElementById('signup');
  const button = document.getElementById('submit-btn');

  form.addEventListener('submit', function (event) {
    event.preventDefault();
    button.disabled = true; // block double submit

    grecaptcha.ready(function () {
      grecaptcha.execute('YOUR_SITE_KEY', { action: 'signup' }).then(function (token) {
        document.getElementById('g-recaptcha-response').value = token; // fresh token at submit time
        form.submit();
      });
    });
  });
</script>

Secret key 无效或域名不匹配:invalid-input-secret

笼统的“Error verifying reCAPTCHA”背后,服务器日志中往往记录的是 invalid-input-secret:Google 判定 secret key 无效或格式错误。

  • 后端配置与 HTML 中的 site key 和 secret key 被填反。
  • 前端代码与密钥类型不一致。每个密钥在创建时都会指定为 Score-based (v3) 或 Challenge (v2)。
  • 密钥已重新创建,但后端仍在使用旧的 secret key。当前密钥位于 Key Details → Integration → Use Legacy Key。
  • 密钥未关联 Google Cloud 项目。Google 在 2026 年第一季度完成了 Classic 密钥的自动迁移,并限制了未关联 Google Cloud 项目的密钥访问 API。如果今年集成在代码未变的情况下突然失效,先检查这一点。
  • 部署时混用了测试密钥和生产密钥。Google 提供始终通过验证的 v2 测试密钥,因此密钥对只复制了一部分的问题,可能直到上线才暴露。
  • .env 中多余的换行符被包含在 secret key 中。

如果生成 token 的页面不在密钥允许的域名范围内,Enterprise 会返回 DOMAIN_MISMATCH。在本地环境中,你可能会看到 “Localhost is not in the list of supported domains.” 将对应域名准确添加到密钥配置中。对于 localhost,Google 建议使用单独的开发密钥。

开启 Disable domain verification 后,Google 就不再检查 token 的来源,因此你的代码必须比较 hostname,确认它与网站域名一致。

Admin Console 2026:reCAPTCHA 密钥及关联域名列表
Google Cloud Console 中的 reCAPTCHA 密钥及其关联域名(2026)

浏览器中 reCAPTCHA 无法加载:browser-error

browser-error 指发生在服务器参与验证之前的故障,通常是脚本或 iframe 没有完成加载。Enterprise API 将 BROWSER_ERROR 归类为可重试错误,例如网络故障。因此,第一步是再次调用 execute()。

  • 广告或脚本拦截器可能阻止脚本加载。Google 的帮助页面建议停用可能与 reCAPTCHA 冲突的插件。
  • 严格的 Content Security Policy 可能拦截脚本,此时浏览器控制台会显示脚本或 frame 被阻止的消息。Google 的 FAQ 列出了需要加入相应指令的来源:

    script-src  https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/
    frame-src  https://www.google.com/recaptcha/ https://recaptcha.google.com/recaptcha/
    connect-src https://www.google.com/recaptcha/

  • 如果防火墙、代理或 VPN 阻止访问 Google 域名,验证组件也会失效。请在访客所在网络中允许访问 *.google.com、*.gstatic.com 和 *.recaptcha.net。当 www.google.com 无法访问时,Google 建议从 www.recaptcha.net 加载脚本,并相应替换其他 www.google.com/recaptcha/ 引用。
  • 在 api.js 加载完成之前调用 grecaptcha 会失败。将相关调用放在 grecaptcha.ready() 内,或使用 onload 回调。
  • 页面上有多个组件时,如果不传入 ID,grecaptcha.getResponse() 和 grecaptcha.reset() 只会作用于第一个组件。应显式渲染每个组件,并保存 grecaptcha.render() 返回的各个 ID。

对于 v2 checkbox,添加 data-error-callback。按照 Google 的说明,实现这个回调后,你还需要负责提示用户重试。

reCAPTCHA v3 提示“Captcha score is not above the threshold”

这条消息表示 Google 接受了 v3 token,但返回的 score 低于网站或插件设置的 threshold。集成本身在正常运行,需要检查的是阈值设置。

在 Google 的评分体系中,0.0 表示高风险,1.0 表示低风险。Google 在验证挑战策略示例中使用 0.5 作为 threshold,但建议根据真实流量选择阈值。预发布环境的 score 可能与生产环境不同。

  1. 先记录 score,不要立即拦截请求。再按照 Google 的建议,结合控制台中的流量数据选择 threshold。
  2. 为每个操作分别设置 threshold。控制台会提供最常见的十个操作的统计信息。
  3. 对于低 score,优先增加验证步骤,而不是直接拒绝请求。Google 的 Enterprise 文档建议,对低评分的登录尝试使用邮件验证或 MFA。
  4. 检查响应中的 action 是否与你发送的值一致。

例如,邮件订阅表单可以接受 0.3 及以上的 score;登录请求低于 0.7 时,则要求输入邮件验证码,而不是直接拦截。

移动应用需要单独评估。Google 的版本说明提到,2026 年的移动 SDK 调整了评分校准方式。如果升级 SDK 后误报增加,就有必要重新检查应用的 threshold。

在 Enterprise 中,未启用结算的项目只能获得四档 score:0.1、0.3、0.7 和 0.9,而不是 11 档。

	Google Cloud Console 中的 reCAPTCHA Enterprise 评分分析
Google Cloud Console 中的 reCAPTCHA Enterprise 评分分析(示例数据)

如果项目没有有效的结算账号,并且超过每月 10,000 次 assessment 的免费配额,siteverify 会返回 success: true、固定的 0.9 score,以及“Over free quota.”消息。如果所有 score 突然都变成 0.9,先检查配额。

Firebase、Adobe AEM 和 Zoho Forms 中的同类错误

这些平台会用各自的错误消息表示 reCAPTCHA 验证失败。下表列出了对应的原因和修复方法。

平台错误消息原因修复方法
Firebase 手机号认证(Identity Platform)CAPTCHA_CHECK_FAILED : Recaptcha verification failed - SITE_MISMATCHtoken 来自不在密钥允许列表中的域名(Google 员工的答复)将域名添加到 site key 的配置中
Adobe AEM FormsCAPTCHA_VALIDATION, HTTP 400迁移后,表单仍在使用旧的 v2 密钥(Adobe 知识库)更新 Adaptive Forms 的 reCAPTCHA 配置中的密钥
Zoho Forms相同的 reCAPTCHA validation failed 消息Settings 中的 secret key 错误、未通过垃圾信息检查,或 Google 端发生故障(Zoho 帮助文档)检查 Settings 中的 secret key

reCAPTCHA 服务器端验证示例:PHP

如果 reCAPTCHA 在服务器端验证失败,先记录错误码。Google 返回验证不通过,与服务器未能成功请求 Google,是两种需要分别处理的情况。下面的 PHP 示例为这两种情况返回不同的响应。所有密钥都检查 hostname,v3 还会检查 score 和 action。

<?php
$secretKey      = getenv('RECAPTCHA_SECRET');          // legacy secret key, server-side only
$expectedHost   = 'www.example.com';                   // your domain
$expectedAction = 'signup';                            // v3 only: action name set on the client
$threshold      = 0.5;                                 // v3 only: tune using your own traffic data

$token = $_POST['g-recaptcha-response'] ?? '';
if ($token === '') {
    http_response_code(400);
    exit('Please complete the CAPTCHA.');
}

$ch = curl_init('https://www.google.com/recaptcha/api/siteverify');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query([
        'secret'   => $secretKey,
        'response' => $token,
        'remoteip' => $_SERVER['REMOTE_ADDR'] ?? '',
    ]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 10,
]);

$raw = curl_exec($ch);
if ($raw === false) {
    // Network problem between your server and Google, not a reCAPTCHA failure
    error_log('siteverify request failed: ' . curl_error($ch));
    curl_close($ch);
    http_response_code(503);
    exit('Verification service unavailable. Please try again.');
}
curl_close($ch);

$result = json_decode($raw, true);

if (empty($result['success'])) {
    $codes = $result['error-codes'] ?? ['unknown-error'];
    error_log('reCAPTCHA failed: ' . implode(', ', $codes));
    http_response_code(400);
    exit('Verification failed. Please try again.');
}

if (($result['hostname'] ?? '') !== $expectedHost) {
    http_response_code(400);
    exit('Verification failed: unexpected hostname.');
}

// v3 only: score and action checks
if (isset($result['score'])) {
    if (($result['action'] ?? '') !== $expectedAction || $result['score'] < $threshold) {
        http_response_code(403);
        exit('Additional verification required.');
    }
}

echo 'Verification successful';

下面的 v2 checkbox 标记使用了前文提到的 data-expired-callback 和 data-error-callback 属性。

<!DOCTYPE html>
<html>
<head>
  <title>reCAPTCHA v2 checkbox</title>
  <script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
  <form action="verify.php" method="POST">
    <div class="g-recaptcha"
         data-sitekey="YOUR_SITE_KEY"
         data-expired-callback="onCaptchaExpired"
         data-error-callback="onCaptchaError"></div>
    <br>
    <input type="submit" value="Submit">
  </form>

  <script>
    function onCaptchaExpired() { alert('The CAPTCHA expired. Please check the box again.'); }
    function onCaptchaError()   { alert('reCAPTCHA could not load. Check your connection and try again.'); }
  </script>
</body>
</html>

reCAPTCHA Enterprise 与 v2 checkbox:故障位置和原因有何不同

Google 对 Enterprise token 和 v2 checkbox token 采用不同的验证方式。v2 的 siteverify 返回通过或失败的结果,以及简短的错误码;Enterprise assessment 则会更详细地解释 token 被拒绝的原因。产品设计和价格方面的区别,可参阅《reCAPTCHA v2、v3 与 Enterprise:功能与成本对比》。

验证流程与响应内容

使用 v2 checkbox 时,访客点击“我不是机器人”后会获得 token。后端将 token 和 secret key 通过 POST 请求发送给 siteverify。响应包含 success、challenge_ts、hostname,以及存在错误时返回的 error-codes 数组。v2 响应不会包含 score。

Enterprise token 通过 grecaptcha.enterprise.execute() 或页面中渲染的 Enterprise checkbox 获取。验证时,后端需要向以下地址发送 POST 请求,创建 assessment:

https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments

请求体包含 token、site key 和预期操作。Google 还建议发送用户的 User-Agent 和 IP 地址。

{
  "event": {
    "token": "TOKEN",
    "siteKey": "KEY_ID",
    "expectedAction": "login",
    "userAgent": "USER_AGENT",
    "userIpAddress": "USER_IP"
  }
}

响应包含 tokenProperties(valid、invalidReason、hostname、action)和 riskAnalysis(score、reasons)。

在哪里查看验证失败的原因

v2 reCAPTCHA 的错误会以六种错误码之一返回,没有更多细节。如果访客未通过图片挑战,token 就不会生成,服务器端也就没有可分析的内容。

Enterprise 提供的信息更具体。token 被拒绝时,invalidReason 会指出原因,例如 MALFORMED、EXPIRED、DUPE、MISSING、BROWSER_ERROR、UNEXPECTED_ACTION、KEY_MISMATCH 或 DOMAIN_MISMATCH。如果 token 有效但 score 较低,相关原因则通过 riskAnalysis.reasons 返回,例如 AUTOMATION、TOO_MUCH_TRAFFIC 或 LOW_CONFIDENCE_SCORE。其中,LOW_CONFIDENCE_SCORE 表示流量不足,无法进行可靠分析。获取原因代码需要结算账号。

Token 验证方式的区别

siteverify 接口使用 secret key 进行身份验证。assessment 则使用 API key,或具有 reCAPTCHA Enterprise Agent 角色的服务账号。v2 后端只检查 success。Enterprise 后端需要确认 tokenProperties.valid 为 true、操作与预期一致,并且 score 达到设定的 threshold。Enterprise 密钥仍可通过 legacy secret key 使用 siteverify,但 Google 建议新集成使用 CreateAssessment。

控制台中的配置方式

独立的 reCAPTCHA Admin 控制台将密钥创建放在一个表单中。填写 Label,选择密钥类型——Score based (v3) 或 Challenge (v2)——并添加域名,然后点击 Submit 即可创建密钥。

Google Cloud 控制台(Google Cloud Fraud Defense)则分为两步:先在 Keys 标签页点击 Create key,再在打开的表单中填写 Display name、Application type 和 Domain list,旁边还有 Disable domain verification 开关。

自 2026 年 4 月起,reCAPTCHA 已归入 Google Cloud Fraud Defense。Google 表示,这一变化不影响现有功能。

	Google Cloud Console 中的 reCAPTCHA v2 checkbox 设置(2026)
Google Cloud Console 中的 reCAPTCHA 复选框验证设置

使用 policy-based challenge keys 时,如果 score 低于你设置的 threshold,访客就会收到验证挑战。这类密钥自 2025 年 10 月起正式可用。Policy Engine 自 2026 年 7 月起进入 Preview 阶段,支持按 score、IP、User-Agent 或 ASN 设置规则。

Enterprise 与 v2 错误:现象、排查位置和处理方法

现象排查位置处理方法
timeout-or-duplicate(v2)或 EXPIRED / DUPE(Enterprise)服务器日志、invalidReason在提交时获取 token,并且只验证一次
Enterprise 密钥返回 invalid-input-secretKey Details → Integration使用 legacy secret key,或改用 assessment
DOMAIN_MISMATCH 或“Localhost is not in the list of supported domains”密钥的域名列表准确添加对应域名,并为 localhost 使用单独的密钥
score 较低,并返回 LOW_CONFIDENCE_SCOREriskAnalysis.reasons先收集更多流量数据,再决定是否拦截请求

如何修复 reCAPTCHA 验证失败:排查清单

用户排查清单

如果你访问的网站无法通过 reCAPTCHA,通常是浏览器或网络问题,可以先从本地环境排查。

  • 重新加载页面后再提交表单。生成超过两分钟的 token 不再有效。

  • 更新浏览器。Google 支持主流浏览器最新的两个主要版本。

  • 启用 JavaScript。

  • 暂停广告拦截器对当前网站的拦截。

  • 关闭 VPN,或换一个网络重试。

  • 如果问题仍未解决,联系网站管理员。

网站管理员排查清单

如果 reCAPTCHA 问题出现在服务器端,请依次检查以下项目。

  • 确认 site key 和 secret key 属于同一密钥对,且不含多余的空格或换行符。

  • 确认密钥配置包含所有生产环境域名。

  • 确认密钥已关联 Google Cloud 项目。

  • 在表单提交时请求 token。

  • 首次点击后禁用 Submit 按钮。

  • 确保同一 token 不会被验证两次。

  • 表单报错后重置组件,或请求新的 token。

  • 后端对所有密钥检查 hostname,对 v3 额外检查 score 和 action。

  • 在 CSP 中允许 Google 指定的 reCAPTCHA 来源。

  • 根据日志中记录的 score 设置 v3 threshold。

  • 日志只记录错误码和 hostname,不记录 secret key 或完整 token。

  • 验证失败后保留访客已填写的表单内容。
     

robots
立即开始自动化您的工作流 reCAPTCHA v2

相关阅读

使用 CapMonster Cloud 自动化测试 reCAPTCHA 表单

测试自己的表单时,CapMonster Cloud API 支持 reCAPTCHA v2、reCAPTCHA v3 和 reCAPTCHA Enterprise,包括 RecaptchaV2Task、RecaptchaV3TaskProxyless、RecaptchaV2EnterpriseTask 和 RecaptchaV3EnterpriseTask 等任务类型。各任务的配置方法和参数说明见 CapMonster Cloud reCAPTCHA 文档。


NB: 请注意,本产品仅用于对您自身的网站以及您依法拥有访问权限的资源进行自动化测试
ItGuy
geear
面向软件开发者的联盟计划
通过用户识别验证码的消费获取高达 30% 的返佣。
✅ 请求已发送
感谢您对我们的合作伙伴计划感兴趣!我们将在 7 个工作日内与您联系。
请求加入
填写表格以提交申请加入合作伙伴计划。