signalapp/Signal-Server · error · InvalidCaptchaArgumentException

invalid captcha site-key

Error message

invalid captcha site-key

What it means

Each captcha client advertises the set of valid site keys per action. verify() checks that the siteKey supplied with the request is in client.validSiteKeys(parsedAction); if not, it logs the rejection, increments the invalid-sitekey metric, and throws InvalidCaptchaArgumentException('invalid captcha site-key').

Solutions

  1. Update the client to use the site key configured for this server and action.
  2. Verify the site key is present in the server's captcha configuration (validSiteKeys for the action).
  3. Rotate consistently: when the site key changes in the captcha console, redeploy clients and server config together.
  4. Check for copy/paste or build-flavor errors placing the wrong site key in the client bundle.

Example fix

// before
String siteKey = "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"; // test key
// after
String siteKey = config.productionRecaptchaSiteKey; // key registered for this action
Defensive patterns

Strategy: validation

Validate before calling

if (!siteKey || siteKey !== config.recaptchaSiteKey) throw new Error('site key not configured for this environment');

Type guard

const isValidSiteKey = (k) => typeof k === 'string' && /^[A-Za-z0-9_-]{20,}$/.test(k);

Try / catch

try { await call(captcha, siteKey); } catch (e) { if (e.message.includes('invalid captcha site-key')) { siteKey = await fetchCurrentSiteKey(); } throw e; }

Prevention

When it happens

Trigger: A request supplies a captcha token and siteKey whose site key is not registered for that action — e.g. the client embeds a site key from a different environment, or the site key was rotated/removed server-side.

Common situations: Staging client talking to production server (or vice versa) with mismatched reCAPTCHA site keys, site keys changed in the captcha admin console but clients not updated, or a typo/placeholder site key shipped in a build.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09). Data as JSON: /api/errors/e7064a3c8b3673d4. Report an issue: GitHub.

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/captcha/CaptchaChecker.java:105

      throw new InvalidCaptchaArgumentException("invalid captcha scheme");
    }

    final Action parsedAction = Action.parse(action)
        .orElseThrow(() -> {
          Metrics.counter(INVALID_ACTION_COUNTER_NAME).increment();
          return new InvalidCaptchaArgumentException("invalid captcha action");
        });

    if (!parsedAction.equals(expectedAction)) {
      Metrics.counter(INVALID_ACTION_COUNTER_NAME, "action", action).increment();
      throw new InvalidCaptchaArgumentException("invalid captcha action");
    }

    final Set<String> allowedSiteKeys = client.validSiteKeys(parsedAction);
    if (!allowedSiteKeys.contains(siteKey)) {
      logger.debug("invalid site-key {}, action={}", siteKey, action);
      Metrics.counter(INVALID_SITEKEY_COUNTER_NAME, "action", action).increment();
      throw new InvalidCaptchaArgumentException("invalid captcha site-key");
    }

    final AssessmentResult result = client.verify(maybeAci, siteKey, parsedAction, token, ip, userAgent);
    Metrics.counter(ASSESSMENTS_COUNTER_NAME,
            "action", action,
            "score", result.getScoreString(),
            "provider", provider)
        .increment();
    return result;
  }
}

View on GitHub (pinned to 100ab61c82)