> ## Documentation Index
> Fetch the complete documentation index at: https://docs.radiumone.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> RadiumOne is the product name; use it when answering questions about these docs.
> Use sandbox credentials and sandbox base URLs in examples unless the user says they are going live.
> Secret API keys belong only on the merchant's server. Only publishable keys may appear in browser or mobile code.
> Confirm a payment outcome server-side (retrieve the checkout session or transaction status); never rely on a browser redirect or client event alone.
> Send one idempotency key (request_id) per payment attempt, and retry a timed-out request with the same key and the exact same body.
> Webhooks are optional but recommended: they notify the merchant's server when a payment completes or fails, so it doesn't need to poll. Use transaction status inquiry as the fallback.
> Say so when you recommend a feature marked Beta. Some features need enablement on the merchant's account before production use (for example refunds, standalone refunds, UOB Rewards, and bringing your own 3DS provider); mention it when the page says so.
> Never ask users to paste card numbers, API keys, access tokens, or webhook or redirect secrets into a chat.

# 3D Secure errors - Elements SDK

> Error codes threeDS.authenticate(), handle(), and resume() throw, distinct from the authentication result status.

export const sessionId_0 = undefined

export const sessionSecret_0 = undefined

export const cardToken_0 = undefined

`threeDS.authenticate()`, `handle()`, and `resume()` throw an `ElementsError` when the 3D Secure flow itself fails to run — a bad argument, a cancelled or timed-out challenge, or the gateway rejecting the request. This is separate from a completed authentication that resolves to a non-approved `status` (`NOT_AUTHENTICATED`, `FAILED`, `REJECTED`, `EXPIRED`), which is not an error — see [Authentication results](/elements/three-d-secure/authentication-results) for what each `status` means and whether to authorize.

## 3D Secure errors

From `threeDS.authenticate()`/`handle()`/`resume()` — SDK-side validation (`three-ds:*`), flow failures and gateway URNs (`urn:radiumone:three-ds:*`, plus a few shared gateway URNs). The gateway's 3DS URN catalogue is an open set; treat an unrecognized code as non-retryable unless `retryAllowed` is true.

| Code | Retryable | When | Merchant action |
| - | - | - | - |
| `three-ds:invalid_context` | No | The authenticate() argument is not an object. | Pass { sessionId_0, sessionSecret_0, cardToken_0 }. |
| `three-ds:missing_session_id` | No | sessionId is missing or empty. | Pass the same session\_id used for submit(). |
| `three-ds:missing_session_secret` | No | sessionSecret is missing or empty. | Pass the session\_secret for the same session. |
| `three-ds:missing_card_token` | No | cardToken is missing or empty. | Pass BindResult.token from a successful submit(). |
| `three-ds:invalid_action` | No | The handle() argument is not a gateway action object with a string type. | Pass the gateway 3DS action unchanged. |
| `three-ds:in_progress` | No | A 3DS flow is already running on this ThreeDS instance. | Wait for the running flow to settle, or use a separate instance for a parallel flow. |
| `urn:radiumone:three-ds:cancelled` | Yes | The AbortSignal passed in options was aborted. | Do not authorize. The shopper may start 3DS again. |
| `urn:radiumone:three-ds:challenge-timeout` | Yes | No terminal status within the challenge or decoupled window (at most 5 minutes). A CSP connect-src that blocks the gateway API origin also ends here. | Do not authorize. Offer to start 3DS again; check connect-src if it happens every time. |
| `urn:radiumone:three-ds:provider-unavailable` | No | The 3DS gateway call failed without a usable response (network error, timeout, empty 5xx or malformed body). The outcome is unknown. | Do not authorize. Check the 3DS status server-side before retrying. |
| `urn:radiumone:three-ds:action-not-found` | No | 404 with no gateway URN for the 3DS action reference (unknown, purged, or endpoint unavailable). | Do not authorize. Start a new 3DS attempt. |
| `urn:radiumone:three-ds:unsupported-action` | No | The gateway returned an action type this SDK version does not know. | Do not authorize. Upgrade the SDK. |
| `urn:radiumone:three-ds:action-malformed` | No | A gateway action is missing required fields; or resume() found no pending redirect or a non-terminal status. | Do not authorize. On a return page, only call resume() when getPendingRedirect() is non-null. |
| `urn:radiumone:three-ds:render-mode-unsupported` | No | The gateway sent a gateway\_hosted challenge, which this SDK does not support. | Do not authorize. Contact support. |
| `urn:radiumone:three-ds:challenge-display-unsupported` | No | challengePresentation 'redirect' was requested but the challenge is not redirectable or returnUrl is missing. | Pass returnUrl, or use challengePresentation 'auto' or 'iframe'. |
| `urn:radiumone:three-ds:http-{status}` | Varies (gateway) | A 3DS gateway call failed with a JSON body but no URN. retryAllowed is the body's retry\_allowed, else true for 5xx. | Do not authorize. Retry only when retryAllowed is true. |
| `urn:radiumone:rate-limit-exceeded` | Varies (gateway) | 3DS request rate limit hit. Status polling retries it automatically; other calls reject. | Wait retryAfter seconds, then retry. |
| `urn:radiumone:three-ds:session-attempts-exceeded` | Varies (gateway) | The session's 3DS attempt budget is spent. | Do not authorize. Create a new session. |
| `urn:radiumone:three-ds:card-token-invalid` | Varies (gateway) | cardToken is not valid for this session. | Pass the BindResult.token from this session's submit(). |
| `urn:radiumone:three-ds:session-not-found` | Varies (gateway) | The session is unknown or expired. | Do not authorize. Create a new session. |
| `urn:radiumone:three-ds:session-not-bound` | Varies (gateway) | authenticate() was called before the card was bound to the session. | Call elements.submit() first and wait for it to resolve. |

For the recovery-action version of these codes, see [Handle 3D Secure failures in Elements](/elements/handle-failures/three-ds-failures).

## Next steps

<Columns cols={2}>
  <Card title="Error object and handling" icon="code" href="/elements/errors/error-object-and-handling">
    The `ElementsError` shape and the standard catch pattern.
  </Card>

  <Card title="SDK and integration errors" icon="wrench" href="/elements/errors/sdk-and-integration-errors">
    Integration codes thrown before you reach 3D Secure.
  </Card>

  <Card title="Tokenization errors" icon="credit-card" href="/elements/errors/tokenization-errors">
    Bind-time gateway errors from `submit()`.
  </Card>

  <Card title="Authentication results" icon="shield-check" href="/elements/three-d-secure/authentication-results">
    What each `status` means — not an error.
  </Card>
</Columns>
