Budibase/budibase · error · UnexpectedError

Failed to verify recaptcha token - ${error.message}

Error message

Failed to verify recaptcha token - ${error.message}

What it means

If the server-side call to Google's `https://www.google.com/recaptcha/api/siteverify` throws (network failure, timeout, 5xx), `verify` wraps the underlying error in an `UnexpectedError` with this message, preserving the original message. It signals the verification attempt itself failed, not that the token was invalid — a `verified: false` response is returned when Google answers with success=false.

Source

Thrown at packages/server/src/api/controllers/recaptcha.ts:61

    const { success } = await response.json()
    const verified = success === true
    if (verified) {
      const sessionId = await setRecaptchaVerified()
      const session: RecaptchaSessionCookie = {
        sessionId,
      }
      utils.setCookie(ctx, session, Cookie.RecaptchaSession, {
        sign: true,
        sameSite: "none",
      })
    }

    ctx.body = {
      verified,
    }
  } catch (error: any) {
    throw new UnexpectedError(
      `Failed to verify recaptcha token - ${error.message}`
    )
  }
}

export async function check(ctx: Ctx<void, CheckRecaptchaResponse>) {
  const cookie = utils.getCookie<RecaptchaSessionCookie>(
    ctx,
    Cookie.RecaptchaSession
  )
  if (!cookie) {
    ctx.body = { verified: false }
    return
  }
  const verified = await isRecaptchaVerified(cookie.sessionId)
  if (!verified) {
    utils.clearCookie(ctx, Cookie.RecaptchaSession)
    ctx.body = { verified: false }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Ensure the server can reach https://www.google.com/recaptcha/api/siteverify (test with `curl -I` from the host/container)
  2. Configure proxy support (HTTPS_PROXY env var or an HTTP agent) for the Node process
  3. Retry the verification after transient network failures
  4. Inspect the wrapped `error.message` for the root cause and fix accordingly
  5. Consider mocking/short-circuiting reCAPTCHA verification in offline dev environments

Example fix

// before
// container has no egress -> verify throws UnexpectedError
// after: set proxy env for the server process
// docker-compose.yml
// environment:
//   - HTTPS_PROXY=http://proxy.corp:8080
//   - NO_PROXY=localhost,127.0.0.1
Defensive patterns

Strategy: try-catch

Validate before calling

async function canReachGoogle() {
  try { const r = await fetch("https://www.google.com/recaptcha/api/siteverify", { method: "HEAD" }); return r.ok || r.status < 500 } catch { return false }
}
// gate verification on canReachGoogle()

Try / catch

try {
  const res = await verifyRecaptcha({ token })
} catch (e) {
  if (String(e.message).startsWith("Failed to verify recaptcha token")) {
    // network-level failure: retry with backoff or degrade gracefully
  }
}

Prevention

When it happens

Trigger: Network egress to google.com blocked (firewall/proxy/air-gapped env), DNS failure, TLS issues, request timeout, or any exception thrown while contacting or parsing the Google siteverify response.

Common situations: Corporate firewalls blocking outbound HTTPS to google.com; running self-hosted Budibase in a container without internet; transient Google outages; proxy env vars not set for the Node process; IPv6/DNS misconfiguration.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/fac8d7c6e237eda1. Report an issue: GitHub.