diff --git a/src/content/docs/en/basics/error-reference.mdx b/src/content/docs/en/basics/error-reference.mdx new file mode 100644 index 0000000000000..1887483f3d87b --- /dev/null +++ b/src/content/docs/en/basics/error-reference.mdx @@ -0,0 +1,347 @@ +--- +title: Error Reference +description: Every error message Procaptcha can display in place of the widget, what causes it, and how to clear it. +i18nReady: true +--- + +When Procaptcha cannot show a challenge, it replaces the widget with a short error message. This page lists every +message a visitor can see, what causes it, and what to do about it. + +## Reading an error + +Each error has two identities: + +- **The message**, e.g. `Site key not registered`. This is what your visitor sees, and it is translated into their + language. A German visitor sees `Site Key nicht registriert` for the same error. +- **The key**, e.g. `API.SITE_KEY_NOT_REGISTERED`. This never changes and is never translated, so it is what you should + search for, log, and quote to support. + +The message is on screen. To find the key, open your browser's developer tools, go to the **Network** tab, reload the +page, and look at the response from the request to `/v1/prosopo/provider/client/captcha/…`: + +```json +{ + "error": { + "message": "Site key not registered", + "key": "API.SITE_KEY_NOT_REGISTERED", + "code": 400 + } +} +``` + +:::note[The error callback receives the message, not the key] +The `error-callback` you configure on the widget is called with a standard `Error` whose `message` is the translated +string. If you want to branch on a specific error in your own code, read the `key` from the network response rather +than matching on message text, which changes with the visitor's language. +::: + +## Quick reference + +| Message | Key | Whose problem is it? | +| --- | --- | --- | +| `Site key not registered` | `API.SITE_KEY_NOT_REGISTERED` | [Your configuration](#site-key-not-registered) | +| `Invalid site key` | `API.INVALID_SITE_KEY` | [Your configuration](#invalid-site-key) | +| `Unauthorized origin URL` | `API.UNAUTHORIZED_ORIGIN_URL` | [Your configuration](#unauthorized-origin-url) | +| `Incorrect CAPTCHA type` | `API.INCORRECT_CAPTCHA_TYPE` | [Usually your configuration](#incorrect-captcha-type) | +| `Procaptcha requires a secure (HTTPS) connection` | `WIDGET.INSECURE_CONTEXT` | [Your configuration](#procaptcha-requires-a-secure-https-connection) | +| `No session found` | `CAPTCHA.NO_SESSION_FOUND` | [Transient, self-healing](#no-session-found) | +| `Cannot load CAPTCHA` | *(none)* | [Transient, self-healing](#cannot-load-captcha) | +| `Frictionless response missing captchaType; halting captcha mount` | *(none)* | [This visitor was blocked](#frictionless-response-missing-captchatype-halting-captcha-mount) | +| `Forbidden: ` | *(none)* | [This visitor was blocked](#forbidden-request-id) | +| `Error parsing captcha` | `CAPTCHA.PARSE_ERROR` | [Unexpected](#error-parsing-captcha) | +| `BadRequest` | `API.BAD_REQUEST` | [Unexpected](#badrequest) | + +## Configuration errors + +These come from how your site key or your markup is set up, so they usually affect **every** visitor, including you. +If you can reproduce the error yourself, it is almost certainly one of these. Fix them in the +[Prosopo portal](https://portal.prosopo.io) or in your widget markup. + +### Site key not registered + +**Key:** `API.SITE_KEY_NOT_REGISTERED` · **HTTP:** 400 + +**What it means.** The site key in your widget is a valid, well-formed key, but Prosopo has no record of it. + +**What causes it.** + +- Your account was created but never activated, so the site key was issued and not yet enabled. +- The site key was deleted from your account, or belongs to an account that has been closed. +- You copied a site key from an example, a tutorial, or another organisation's site. +- You are pointing a production site key at a development environment, or vice versa. + +**How to fix it.** + +1. Check your email for the Prosopo activation link and click it. This is the cause the majority of the time. +2. Log in to the [Prosopo portal](https://portal.prosopo.io) and confirm the site key is listed and active. +3. Copy the site key straight from the portal into your `data-sitekey` attribute — do not retype it. +4. If the key is listed as active and the error persists, + [contact support](mailto:support@prosopo.io) quoting the site key. + +### Invalid site key + +**Key:** `API.INVALID_SITE_KEY` · **HTTP:** 400 + +**What it means.** The value you supplied is not a well-formed Prosopo site key at all, so it was rejected before any +lookup happened. This is a different failure from [`Site key not registered`](#site-key-not-registered), where the key +was well-formed but unknown. + +**What causes it.** + +- A truncated or partially copied key. +- Stray whitespace, quotes, or a trailing comma inside the `data-sitekey` attribute. +- A template placeholder that was never substituted, such as `data-sitekey="{{ SITE_KEY }}"`. +- Your **secret** key pasted where the **site** key belongs. The secret key is for server-side verification only and + must never appear in your HTML. + +**How to fix it.** + +1. Log in to the [Prosopo portal](https://portal.prosopo.io) and copy the site key. +2. Confirm your rendered HTML contains the full key with no surrounding whitespace: + + ```html +
+ ``` + +3. If you inject the key from a server-side template or an environment variable, view the page source in the browser + and confirm the variable was actually interpolated. + +### Unauthorized origin URL + +**Key:** `API.UNAUTHORIZED_ORIGIN_URL` · **HTTP:** 400 + +**What it means.** The site key is valid and registered, but the domain the widget is running on is not on that key's +list of allowed domains. + +**What causes it.** + +- The site is being served from a domain you have not added yet — commonly a staging, preview, or branch-deploy URL. +- A `www.` versus bare-domain mismatch, or a country domain you did not register alongside the main one. +- Local development on `localhost` or `127.0.0.1` with a site key registered only for production. +- The widget is embedded in an iframe hosted on a third-party domain, which makes the *embedding* domain the origin. + +**How to fix it.** + +1. Log in to the [Prosopo portal](https://portal.prosopo.io) and open the site key's settings. +2. Add the exact domain shown in your browser's address bar to the allowed domains. +3. Add every domain you deploy to, not just production — staging and preview URLs each need an entry. +4. Reload the page. Domain changes take effect immediately. + +### Incorrect CAPTCHA type + +**Key:** `API.INCORRECT_CAPTCHA_TYPE` · **HTTP:** 400 + +**What it means.** A challenge was requested for one [captcha type](/en/basics/captcha-types) when Prosopo expected a +different one. Current versions of the widget are told which type to use by the server, so this points either at a +client that bypassed that step, or at a stale session. + +**What causes it.** + +- **A direct API integration** requesting `/captcha/pow`, `/captcha/image`, or `/captcha/puzzle` for a type that does + not match the one configured on the site key in the portal. +- **A very old copy of the Procaptcha bundle** that still honours a `data-captcha-type` attribute on your markup and + requests that type directly. Current bundles ignore the attribute entirely. +- **A stale session.** The widget carried on with a session whose type no longer matches — for example a page restored + from the browser's back/forward cache, or a challenge that was escalated to a second stage the host page did not + follow. +- **An access control rule** pinning a specific captcha type for this visitor that differs from the one requested. + +**How to fix it.** + +1. If a visitor hits this once and a refresh clears it, it was a stale session. No configuration change is needed. +2. Make sure you are loading the current Procaptcha bundle. If your markup still carries `data-captcha-type`, remove + it — the type is chosen by Prosopo and the attribute has no effect on current bundles. +3. If you integrate against the API directly, request the captcha type that the site key is configured for in the + [Prosopo portal](https://portal.prosopo.io). +4. If it is persistent for one visitor but not others, check your + [access control rules](/en/advanced/access-control-rules) for a rule pinning a captcha type. + +### Procaptcha requires a secure (HTTPS) connection + +**Key:** `WIDGET.INSECURE_CONTEXT` · **HTTP:** *(no request is made)* + +**What it means.** The page is not running in a [secure browser context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts). +Procaptcha depends on browser cryptography APIs that browsers only expose over HTTPS, so it stops immediately rather +than failing later with a confusing message. + +**What causes it.** + +- The page was loaded over plain `http://`. +- A local development server bound to a LAN address such as `http://192.168.1.10:3000`. Browsers treat `localhost` as + secure, but not other IP addresses. +- The page is embedded in an iframe served over plain HTTP, which makes the whole context insecure. + +**How to fix it.** + +1. Serve the page over HTTPS. In production this is required, not optional. +2. In local development, use `http://localhost` (which browsers already treat as secure) rather than a LAN IP. +3. If you must test from another device on your network, put a local HTTPS proxy or tunnel in front of your dev server. + +## Transient errors + +These clear on their own. Neither one means anything is misconfigured, and neither needs action from your visitor +beyond waiting. + +### No session found + +**Key:** `CAPTCHA.NO_SESSION_FOUND` · **HTTP:** 400 + +**What it means.** The widget tried to continue a challenge whose session the provider no longer holds. Sessions are +single-use and time-limited by design. + +**What causes it.** + +- The visitor left the page open long enough for the session to expire before interacting with the widget. +- The page was restored from the browser's back/forward cache with a session that had already been used. +- The visitor's browser blocked or cleared the storage the widget uses to hold the session. + +**How to fix it.** + +1. Do nothing. The widget detects this specific error and automatically resets itself after about 10 seconds, at which + point the visitor can solve a fresh challenge. +2. If the visitor is impatient, refreshing the page resolves it immediately. +3. If it happens on *every* attempt and never recovers, clear the browser's cache and cookies and try again, then + [contact support](https://discord.com/invite/3nMYAHecZT). + +### Cannot load CAPTCHA + +**Key:** *(none — this is a fallback message)* · **HTTP:** *(varies)* + +**What it means.** The widget tried five times to reach a Prosopo provider and failed each time, or it received a +failure with no message attached. This is the generic last-resort message shown when nothing more specific is known. + +**What causes it.** + +- A transient network problem between the visitor and Prosopo. +- The visitor's network, corporate proxy, DNS filter, or browser extension is blocking requests to Prosopo. +- A Content Security Policy on your site that does not allow the widget to reach Prosopo. +- A provider-side incident. + +**How to fix it.** + +1. Do nothing first. The widget reloads itself roughly 10 seconds after giving up, and transient failures usually clear + on the retry. +2. If it is reproducible, open developer tools and check the **Network** tab and **Console** for blocked requests. A CSP + violation or an `ERR_BLOCKED_BY_CLIENT` entry points at a policy or extension on the visitor's side rather than at + Prosopo. +3. Check that your Content Security Policy permits the widget's requests to Prosopo. +4. If requests are reaching Prosopo and still failing for many visitors, + [contact support](https://discord.com/invite/3nMYAHecZT). + +## Blocked visitors + +These two messages mean Prosopo refused the request outright. Only the affected visitor sees them; the rest of your +traffic is unaffected. If your own rules caused the block, this is Procaptcha working as configured. + +:::note[These messages are deliberately vague] +Neither message names the rule that fired. That is intentional — telling an automated client exactly why it was blocked +helps it evade the block. Use the audit log in the portal to see the real reason. +::: + +### Frictionless response missing captchaType; halting captcha mount + +**Key:** *(none)* · **HTTP:** 401 + +**What it means.** Prosopo returned `401 Unauthorized` rather than a challenge, and the widget refused to guess what to +show. The visitor was turned away before any captcha was issued. + +**What causes it.** + +- An [access control rule](/en/advanced/access-control-rules) on your site matched this visitor and is set to block. +- The visitor's bot score exceeded your site's auto-ban threshold. +- The request failed a header integrity check, which usually means it did not come from a genuine browser. + +**How to fix it.** + +- **If this is a real visitor being blocked wrongly**, review your + [access control rules](/en/advanced/access-control-rules) and your + [safety threshold](/en/basics/safety-threshold) in the portal. A threshold set too aggressively is the most common + cause of false positives. +- **If you are testing with a script, `curl`, or a headless browser**, this is the expected outcome. Automated clients + are what the block exists to stop. +- **If you cannot tell which it is**, check the audit log for your site in the + [Prosopo portal](https://portal.prosopo.io) — it records which rule fired for each blocked request. See + [Audit](/en/advanced/audit). + +### Forbidden: `` + +**Key:** *(none)* · **HTTP:** 403 + +**What it means.** The request matched an entry on Prosopo's blocklist and was rejected at the edge, before it reached +any captcha logic. The trailing value is the request ID. + +**What causes it.** + +- The visitor's IP address, network, or client fingerprint is on a blocklist. +- The request came from infrastructure Prosopo has classified as abusive. + +**How to fix it.** + +1. Copy the request ID from the end of the message. It uniquely identifies this request in our logs. +2. If you believe a genuine visitor was blocked, [contact support](https://discord.com/invite/3nMYAHecZT) and quote the + request ID. We can look up the exact rule that fired. +3. Do not ask visitors to retry — a blocklist match will produce the same result every time. + +## Unexpected errors + +If you see either of these, something went wrong that should not have. They are worth reporting. + +### Error parsing captcha + +**Key:** `CAPTCHA.PARSE_ERROR` · **HTTP:** 400 + +**What it means.** Prosopo received a request from the widget that it could not read — a required field was missing, +or a value was not of the expected shape. + +**What causes it.** + +- A modified, out-of-date, or partially loaded copy of the Procaptcha bundle. +- Something on the page or in the network path altering the widget's requests, such as an aggressive optimisation + proxy or a browser extension. +- A client that is imitating the widget rather than being the widget. + +**How to fix it.** + +1. Make sure you are loading the Procaptcha bundle from the official URL and are not pinning an old copy. +2. Hard-refresh (`Ctrl`-`Shift`-`R`) to rule out a stale cached bundle. +3. Reproduce with browser extensions disabled. +4. If it persists on a clean, current bundle, [contact support](https://discord.com/invite/3nMYAHecZT). + +### BadRequest + +**Key:** `API.BAD_REQUEST` · **HTTP:** 400 or 500 + +**What it means.** A catch-all for a request Prosopo could not fulfil. When it carries a 500 it indicates a +provider-side failure rather than anything about your request. + +**What causes it.** + +- A required request header, such as `Origin`, was missing or stripped in transit. +- An internal provider error while building the challenge. + +**How to fix it.** + +1. Retry. Where the cause is provider-side, the widget's own retry usually succeeds against a different provider. +2. Check whether a proxy or CDN in front of your site is stripping the `Origin` header from browser requests. +3. If it is consistent and reproducible, [contact support](https://discord.com/invite/3nMYAHecZT) with the URL and the + time of the failure. + +## Errors that never reach the visitor + +Not every Procaptcha error is displayed. Some are written only to the browser console, so a visitor reporting "the +captcha just doesn't appear" may be hitting one of these. Check the console before assuming a network problem. + +| Console message | Key | Meaning | +| --- | --- | --- | +| `No site key found` | — | The widget element has no `data-sitekey` attribute at all. Add one. | +| `SITE KEY missing` | `GENERAL.SITE_KEY_MISSING` | The widget started without a site key available to it. Same fix. | +| `No Procaptcha containers found for execution` | — | `execute()` was called but no element with the `procaptcha` class exists on the page. | +| `No captchas returned from provider` | `DEVELOPER.PROVIDER_NO_CAPTCHA` | The provider returned an empty challenge. The widget retries automatically. | + +Separately, a visitor who fails a challenge is not shown an error at all — the widget simply resets so they can try +again. Nothing is broken in that case. + +## Still stuck? + +Have your site key and, if you have one, the request ID to hand, then reach us on +[Discord](https://discord.com/invite/3nMYAHecZT) or at [support@prosopo.io](mailto:support@prosopo.io). diff --git a/src/content/docs/en/basics/faq.mdx b/src/content/docs/en/basics/faq.mdx index 5fd308baa2aed..3413cee90f6b7 100644 --- a/src/content/docs/en/basics/faq.mdx +++ b/src/content/docs/en/basics/faq.mdx @@ -4,34 +4,39 @@ description: Common questions and answers about Procaptcha. i18nReady: true --- -### What does `Site Key not Registered` mean? -You may encounter this error when you set up the Procaptcha widget on your website. This error occurs when the site key -you are using is not registered in the Prosopo system. To resolve this error, click the Activation link in the email -or contact the Prosopo support team. +Looking for a specific error message shown in place of the widget? The [Error Reference](/en/basics/error-reference) +covers every one of them, with causes and fixes. -### What does `Invalid Site Key` mean? -This error occurs when the site key you are using is not valid. To resolve this error, ensure that you are using the -correct site key, which you can find by logging in to the [Prosopo portal](https://portal.prosopo.io). +### What does `Site key not registered` mean? +The site key you are using is not registered in the Prosopo system. Most often the account was never activated — click +the activation link in your email, or contact the Prosopo support team. +See [Site key not registered](/en/basics/error-reference#site-key-not-registered). + +### What does `Invalid site key` mean? +The value in your `data-sitekey` attribute is not a well-formed site key — usually truncated, or a placeholder that was +never substituted. Copy the key from the [Prosopo portal](https://portal.prosopo.io). +See [Invalid site key](/en/basics/error-reference#invalid-site-key). ### What does `Unauthorized origin URL` mean? -This error occurs when the domain of the site key does not match the domain of the website where the Procaptcha widget -is being used. To resolve this error, ensure that the domain of the site key matches the domain of the website by -logging in to the [Prosopo portal](https://portal.prosopo.io) and updating the domain. +The domain serving the widget is not on the site key's list of allowed domains. Add it in the +[Prosopo portal](https://portal.prosopo.io), including any staging and preview domains. +See [Unauthorized origin URL](/en/basics/error-reference#unauthorized-origin-url). ### What does `Incorrect CAPTCHA type` mean? -This error occurs when the [captcha type](/en/basics/captcha-types) is not set correctly. The default `captchaType` is -`frictionless`. If you wish to use `pow` or `image` you must set your `captchaType` in the widget configuration to `pow` -or `image`. You must also update your [portal settings](https://portal.prosopo.io) to match. +The [captcha type](/en/basics/captcha-types) your widget requests does not match the one configured for the site key. +The default is `frictionless`; if you set `pow`, `image`, or `puzzle` in your markup you must set the same value in your +[portal settings](https://portal.prosopo.io). +See [Incorrect CAPTCHA type](/en/basics/error-reference#incorrect-captcha-type). -### What does `Session not found` mean? -This error occurs when the session is not found. This can happen if the session has expired or if the session ID is -not valid. To resolve this error, either wait for the widget to reload (3s) or refresh the page. If the error persists, -try clearing your browser cache and cookies. If the error still persists, please [contact the Prosopo support team](https://discord.com/invite/3nMYAHecZT). +### What does `No session found` mean? +The challenge session expired or had already been used. The widget resets itself after about 10 seconds, or you can +refresh the page. See [No session found](/en/basics/error-reference#no-session-found). ### What does `Error parsing captcha` mean? -This error will occur if incorrect data has been sent with the captcha response. To resolve this error, ensure that the -data sent with the captcha response is correct. - - - +Prosopo received a request from the widget it could not read, usually from a stale or modified copy of the Procaptcha +bundle. Hard-refresh and make sure you are loading the official bundle. +See [Error parsing captcha](/en/basics/error-reference#error-parsing-captcha). +### The widget doesn't appear at all, and there is no error message. +Some failures are written only to the browser console rather than being displayed. Open developer tools and check the +console — see [Errors that never reach the visitor](/en/basics/error-reference#errors-that-never-reach-the-visitor). diff --git a/src/i18n/en/nav.ts b/src/i18n/en/nav.ts index 1ae5b5b1f80b6..0b4937f1cc63c 100644 --- a/src/i18n/en/nav.ts +++ b/src/i18n/en/nav.ts @@ -55,6 +55,11 @@ export default [ slug: 'basics/faq', key: 'basics/faq', }, + { + text: 'Error Reference', + slug: 'basics/error-reference', + key: 'basics/error-reference', + }, {text: 'Advanced Usage', header: true, type: 'learn', key: 'advanced'}, { text: 'Context Awareness',