Troubleshooting
Find your symptom, check the cause, apply the fix. Every Chat error body has a stable error code. In the SDKs it is error.code, with the HTTP status in error.status. The full list is in the error catalog.
Is it the Identity Server?
Section titled “Is it the Identity Server?”Most first-time failures are configuration at the Identity Server, not Chat. Check these before you debug code.
- Audience. Decode the token. For a user token
audmust bechat-api. Your backend asks for it withresourceset to the Chat API’s resource identifier, never the audience.resource=chat-apifails withinvalid_target. - Scope. A user token must carry
chat:access. A machine token needschat:syncor a granular scope. See Scopes. - Client grants. The backend client needs Resource Permissions on the Chat API. To hand users a token it also needs the token exchange grant and the permission to exchange for
chat:access. See Register the backend client and Enable token exchange. - Origins. Your web app’s origin must be in
allowed_originson its client. See Register web origins. - User access. The user must be an active member of the tenant with access to your application.
As a rule, a 401, a CORS error, client_context_mismatch, insufficient_scope and no_application_access usually point to the Identity Server. missing_capability, not_conversation_member and the 422 errors are Chat-side. Local development shows which token claims to check.
Errors from the Chat API
Section titled “Errors from the Chat API”| Symptom | Cause | Fix |
|---|---|---|
401 invalid_token |
Wrong aud (a token for your own API), an expired token, or no chat:access scope. |
Use the exchanged Chat token. Renew it before it expires. See Get the user’s Chat token. |
403 client_context_mismatch |
The token was issued to a client of another tenant or application than the one in the URL. | Use the tenant and application of the client that issued the token. For an exchanged token that is your backend client’s application. |
403 missing_capability |
The caller lacks the Chat permission named in message, in this application. |
A tenant administrator grants it to the user’s role in Chat Administration, for this application. See Grant permissions to roles. Machines get it through a scope, and some are never available to them. |
403 not_conversation_member |
The user is not an active member and the conversation is not a PUBLIC channel. | Add the user from your backend, or have them join the PUBLIC channel. |
403 principal_not_allowed or 400 user_required |
A machine token called a user-only route, such as the realtime token, reactions, read state or typing. | Call it with a user token from token exchange. |
404 not_found on a conversation that exists |
It belongs to another tenant or application, or the user cannot read it. Chat never says which. | Check tenantId, applicationId and the conversation id. |
422 target_user_not_eligible |
A referenced user is not an active tenant member with access to the application. | Check the user in the Identity Server. A newly added user can take a short time to appear. |
422 conversation_archived |
Someone posted to an archived conversation. | Reactivate it from your backend if the relationship resumes. |
429 rate_limited |
A rate limit was exceeded: 30 messages per 10 s per user, 20 lookups per 10 s per user, or 600 requests per 60 s per client. | Wait the Retry-After header’s seconds (retryAfterSeconds in the SDKs), then retry. Throttle typing signals. |
503 identity_unavailable |
Chat could not reach the Identity Server and has no fresh answer. | Retry with backoff. |
500 server_error |
An unexpected error in Chat. | Retry with backoff. If it persists, contact support with the timestamp and path of the response. |
Token exchange
Section titled “Token exchange”| Symptom | Cause | Fix |
|---|---|---|
invalid_grant from your token route |
The user’s own token expired or their session ended. The Identity Server returns this to your backend. | Renew the user’s sign-in, then retry. |
| Exchange is refused | Token exchange is not enabled on the Identity Server, or your backend client lacks the permission to exchange for chat:access. |
See Enable token exchange and the Identity Server’s token exchange guide. |
access_denied |
The user lost access to the application. | Restore access in the Identity Server. |
invalid_target |
resource is the audience, not the identifier. |
Send the Chat API’s resource identifier. |
In the browser
Section titled “In the browser”| Symptom | Cause | Fix |
|---|---|---|
| CORS error in the console | Your app’s origin is not in allowed_origins on its Identity Server client. |
Add the exact origin (scheme, host and port). It takes effect in about a minute. Nothing is configured on the Chat side. |
Realtime state stays disconnected or error |
The realtime-token request failed or answered with an empty object because realtime is not available. |
Turn on debug: true, open the network tab and check that request. See below. |
| Push prompt never shows | register() ran without a click, the browser is unsupported, permission was already denied, or the service worker did not register. |
Call it from a click and check isSupported(). Serve /push-sw.js as JavaScript from the site root. A denied site must be unblocked in browser settings. |
Realtime stays disconnected
Section titled “Realtime stays disconnected”Check the realtime-token request in this order.
- Empty response (
{}). Realtime is not configured for the deployment. Ask support. See Support. - 401, or no request at all. The token expired, or
getAccessTokenreturned nothing or threw. Fix the token function. - 403
client_context_mismatch. ThetenantIdorapplicationIdis not your application’s. - 403
principal_not_allowed. A machine token was used. Realtime is for users. - After six failed retries. The client waits in
error. Calldisconnect(), thenconnect().