Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Troubleshooting

This page lists the problems you will encounter in integration as a symptom, cause, fix triple. Find the symptom from the error code or the status code. For the full code tables, see the error reference.

Note

When reporting a problem, include: the path and method called, the status code and body (with secret values removed), the request time (UTC), and on plugin endpoints the x-request-id/requestId. The server does not leak error detail outward; this information speeds up the investigation.

Identity and session

SymptomLikely causeFix
Server call 401 unauthorizedThe Authorization: Bearer crx_live_… header is missing or its format is wrong; the key was revoked, disabled, or expired; the key belongs to another environmentCheck the header and the key; look at the key’s state and environment in the panel (API keys). The server does not distinguish “wrong key” from “revoked”
Server call 403 permission deniedYou are calling a server endpoint with a client keyUse a server key (endpoints: the endpoints marked “Server key”)
Player call 401The x-crx-env header is missing or not a UUID; the session is missing, expired, or revoked; the environment does not matchAdd the header; refresh the session or sign in again. A banned account also looks like 401 (no distinction is made)
Player 403 permission denied (POST)The CSRF pair is missing/does not match; the token was already used; Origin is not allowedSee the CSRF rows below
403 and {"code":"account_banned"} at sign-inThe account is bannedShow the player a suspension screen; do not build a retry loop; do not open a new guest
The session ends earlier than expectedNo request was made for 30 days; or the 180-day absolute ceiling was reached; the password changed (all sessions drop); “single active session” is on in the environment and a sign-in was made from another deviceBuild a sign-in-again flow; the behavior is on the security page
The session cookie is never set in the browserYou are working over HTTP (Secure + the __Secure- prefix); the API is on another domain (the cookie becomes third-party, SameSite=Lax); the browser blocks cookiesUse HTTPS and the same origin (architecture and hosting)
429 rate limited on sign-in/sign-upThe per-IP rate limit is full (guest 30/min, email sign-in 5/min…)Wait; if many players come from one IP or the proxy does not forward the client IP, see rate limits and the production checklist
Email sign-in fails, the password is correctFailed-attempt lock (10 per 15 min per address + IP)Wait 15 minutes or reset the password

CSRF and Origin

SymptomLikely causeFix
Every POST 403The x-csrf-token header or the __Secure-crx.csrf cookie is not being sentGet a token with GET /v1/auth/csrf; send the cookie and the header together. The SDK does this automatically
The first POST passes, the second 403The CSRF token is single-use and renewed with every successful response; you did not store the response’s new value, or you sent two requests in parallel with the same tokenUse the new x-csrf-token and Set-Cookie value in each response; put modifying requests in a queue
403 only in the browser, works in curlOrigin is not in the environment’s allowed origins; a navigation request with Sec-Fetch-Site: cross-siteDefine the game’s domain as an environment domain (Game settings: environments); call the API from the same origin
A “CORS policy” error in the browser consoleThe game’s domain is in no environment’s domain list or the global allowed list (the server sends no CORS to that origin); or the origin is not https://<domain> (http, a port, null)Add the domain as an environment domain (Game settings: environments); if that is not possible, set up a same-origin reverse proxy. Do not add extra CORS headers to your proxy

Call errors

SymptomLikely causeFix
404 and JSON module_disabled (the module field)The product module is disabled in the environmentEnable the module in the panel (modules)
404 not foundThe resource does not exist, was deleted, or the wrong environmentCheck the ID and the environment
A 400 message like “Idempotency-Key required”The header is missing on an endpoint where the key is required, or it is empty/200+ charactersAdd the header (idempotency)
400 “must be a valid UUID”On a clan, group, or tournament endpoint the key is not a UUIDGenerate a UUID v4
400 If-Match error*, W/"3", a negative or non-numeric valueSend the exact version number (3 or "3")
409 version conflictThe resource changed after you read itRe-read, repeat with the new version
409 idempotent request in progressThe request with the same key is still being processedRepeat shortly with the same key
422 idempotency mismatchYou used the same key with a different bodyA new key for every different operation; do not change the body when repeating the same operation (remember that the key is unique across the environment)
422 unprocessable: …A business rule rejection (balance, stock, limit)Read the state and show it to the user; do not repeat the same request
410The key’s 24-hour record retention expiredRead the state and, if the operation was not applied, restart it with a new key
413The body is above 2 MiBShrink the body; for images use the image upload endpoint
429Rate limit or rule budgetWait and repeat with the same key; for the rule budget simplify the rule
503 and Retry-After: 30The environment’s placement is temporarily unavailableWait for Retry-After and repeat
A big number is corrupted (9007199254740992 instead of 9007199254740993)You read the JSON with JSON.parse; int64 did not fit in a JS numberUse the SDK’s bigint reading or lossless-json (numbers)
An SDK error of type ContractThe response does not conform to the schema the SDK knows (the server is newer) or the response is above 2 MiBUpdate the SDK; match the server and SDK versions

Plugins

SymptomLikely causeFix
403 and forbiddenThe plugin is not enabled in the environment (read-only, draining, disabled) or the environment’s plugin version does not match the server’s; CSRF/Origin rejectionLook at the plugin’s state and version in the panel (Plugins)
400 and invalid_argument (“x-crx-schema-version is required”)The x-crx-schema-version header is missing or the schema version is wrong; the payload does not conform to the schema; the same parameter twice in a queryVerify the operation’s schemaVersion value and the input schema from the schema document
404 and not_foundThe plugin ID or the message type is wrong; you confused the message type with the operation nameWrite the requestMessageType value in the schema document into the path
409 idempotency_in_flightThe command with the same key is being processedretryable: true; wait and repeat with the same key
422 unprocessable + reasonA plugin business rule rejectionreason is a plugin-specific code; see the plugin’s documentation; repeating does not help
The command result is uncertainThe network droppedQuery with …/result?idempotency_key=… or repeat with the same key (calling plugins)
SDK upgrade_required (plugin_binding_mismatch)The binding’s pin does not match the expectation you hold or the document on the serverGet the current document and regenerate the binding (bindings)
Cannot find module '@open-play/sdk/player' in the generated bindingThe generator writes the import with the name @open-play/sdk; the published package’s name is @ferdiunal/open-play-tsDefine an alias in package.json: "@open-play/sdk": "npm:@ferdiunal/open-play-ts@<version>"
crx plugins generate error: CRX TYPES FAILThe digest does not match, the output file already exists, the output folder does not exist, or there is a symbolic link in the pathMatch the digest with the schemaSha256 in the document; delete the existing output; create the folder

Realtime

SymptomLikely causeFix
Ticket request 403An identity, CSRF, Origin, or x-crx-env error (all get the same response)Check CSRF and Origin; the game’s domain must be in the environment domain list
Upgrade 401There is a query string, the openplay.realtime.v1 subprotocol was not requested, or Origin is not allowedProtocol: open the socket
An immediate AuthenticationFailed and closeThe ticket was used (single-use), 30 s expired, or it was obtained from a different Origin; Authenticate did not arrive within 5 sA new ticket on every connection; send Authenticate right after the socket opens
UnexpectedFrameA frame in the wrong phase (Join before authentication, a second Authenticate)Set the order according to the protocol
InvalidPayloadBroken JSON, unknown field, a payload that does not conform to the schema, int64 was sent as a numberSend counters as decimal text; validate the payload against the schema
CapacityExceeded and closeFrame rate above 40/s; 4 sockets per player or 8 per addressReduce sending; close old tabs
The socket closes in 5 minutes (4100)Idle closeA “Continue” flow; keep-alive input (limits)
Inputs get Ack: StaleA newer socket of the same player was openedClose the old socket; work with a single socket
A ResyncRequired loopInsisting on an expired or gapped cursorDiscard the cursor, Join without a cursor
/v1/ws or /v1/chat/ws 401 in the browserThese two sockets require the x-crx-env header on the upgrade; the browser cannot add headersUse REST in the browser (realtime overview)

Webhooks

SymptomLikely causeFix
No request ever arrives at my endpointThe endpoint is not registered, was deleted, or is disabled; the event type is not in the subscription list; the webhooks module is disabled (deliveries wait in place, data is not deleted); the endpoint is not publicly reachableCheck the endpoint and the module in the panel (Webhooks and event queue)
Registration 400The address is not https; it contains a private/loopback IP or user infoProvide a publicly reachable https address (security)
The signature does not matchYou parsed and reserialized the body (raw bytes are needed); the secret is wrong (the whsec_… text itself, not base64); you forgot the t. prefixVerify the raw body; example: security
Timestamp rejectionYour server’s clock has driftedSync the clock with NTP; keep the window at 5 minutes
The same event arrived twiceDelivery is at-least-onceDeduplicate with X-Crx-Event-Id
Deliveries are failedNo 2xx was received in 10 attemptsFix the receiver error. The panel’s deliveries are only for monitoring (there is no resend/replay action); make up for the effect of missed events by reading the relevant resource with REST
A large event did not arriveA body above 64 KiB is not sentShrink the event size

Unity

SymptomLikely causeFix
The package does not install~/.upmconfig.toml or the scoped registry configuration is missing; the token lacks read:packagesThe Unity SDK installation steps
Requests are blocked in WebGLThe game and the API are not on the same origin; the Unity WebGL SDK requires the same origin todaySet up a same-origin reverse proxy (Unity SDK)
UpgradeRequired (plugin_binding_mismatch)The package-ride binding embedded in the package does not match the server’sUpdate the SDK
The session is not restored at runtimeThe default secret storage is not secure (PlayerPrefs)Unity SDK: attach your own secure storage

If it is still not resolved

  1. Repeat the same request with curl (keeping secret values safe); tell apart whether the problem is in the SDK, the network, or the server.
  2. Find the status code in the error reference.
  3. Review the network items in the production checklist (header forwarding, client IP, HTTPS).
  4. Add the information above to your support request.