> TickerLayer documentation for AI agents and LLMs, the Markdown version of https://tickerlayer.com/docs/websocket/troubleshooting
> REST base URL https://api.tickerlayer.com, API key in the `x-api-key` header. WebSocket wss://stream.tickerlayer.com?apiKey=YOUR_API_KEY.
> Any docs page reads as Markdown at its URL plus `.md`. Index: https://tickerlayer.com/llms.txt · Full API reference: https://tickerlayer.com/llms-full.txt

# Errors & troubleshooting

Failures split into two phases: before the WebSocket opens (HTTP status on upgrade) and after connect (JSON error frames sent by the server).

## Upgrade errors

HTTP responses sent before the handshake completes; no WebSocket frames are exchanged. Treat any answer other than `101` as a retry.

| Status | Meaning | What to do |
| --- | --- | --- |
| `401` | Invalid or missing `apiKey`. | Check the key and the parameter name. |
| `403` | Authenticated, but not entitled for WebSocket or the package; the JSON body carries an `error` reason. | Check that your plan includes WebSocket access. |
| `429` | Too many open connections for your account, or global capacity: `{ "error": "WS_CONNECTION_LIMIT_EXCEEDED", "message": "rate limit exceeded" }` | Close a connection or upgrade your package ([Rate limits](https://tickerlayer.com/docs/limits)). |
| `503` | The auth or entitlement check timed out (`Retry-After: 2`), or a release is swapping the serving process (`SERVICE_RESTARTING`, `Retry-After: 1`). | Reconnect after the delay and resubscribe. |

## In-stream error codes

After connect, a failed client action returns a `type: "error"` frame; subscribe failures also set `event: "subscribe_failed"` (or `subscribe_partial_failed`). Rejected symbols are listed in `rejected` when present; there is no `details` object.

| Code | Meaning |
| --- | --- |
| `INVALID_PAYLOAD` | Malformed JSON, a body that is not an object, an unknown action, a missing or bad channels array, a symbols field of the wrong type, or a generic processing failure. |
| `EMPTY_SYMBOLS` | The symbols field is empty after normalization. |
| `TOO_MANY_SYMBOLS` | More than 500 symbols in one subscribe. The message is usually "rate limit exceeded". |
| `SYMBOL_LIMIT_EXCEEDED` | The account or connection distinct-symbol cap. The message is usually "rate limit exceeded". |
| `UNSUPPORTED_CHANNEL` | The channel is not a public channel. |
| `INVALID_CHANNEL` | A known channel your key is not allowed to use (entitlement or package). |
| `INVALID_SYMBOL` | Symbols not enabled for the requested channel; see `rejected`, with optional `channel` and `symbol` fields. |
| `UNSUPPORTED_SYMBOL_FOR_CHANNEL` | A known symbol outside the channel's asset class. |
| `UNAUTHORIZED_SYMBOL` | A symbol your account is not entitled to on that channel. |
| `PARTIAL_SUBSCRIBE_FAILED` | Some symbols subscribed; `rejected` lists the rest (`subscribe_partial_failed`). |
| `MARKET_DATA_CAPACITY` | A temporary capacity limit on activating demand-driven symbols. Retry later. |
| `PACKAGE_EXPIRED` | Your package ended after connect; the connection may be closed. |

## Disconnects

| Close code | Cause | What to do |
| --- | --- | --- |
| `4008` | No pong to the server's native ping frames; a `HEARTBEAT_TIMEOUT` disconnect frame comes first. | Answer pings (most clients do on their own), then reconnect. |
| `1012` | A release replaced the serving process; a `SERVER_RESTART` disconnect frame comes first. | Reconnect right away and resubscribe; the snapshot closes the gap. |
| `1006` | No frame and no close code: not closed by the server, usually a reset on the network path. | Reconnect the same way. |

## Common fixes

- **Check the connect URL:** Use `wss://stream.tickerlayer.com/?apiKey=...`, not the REST base URL, and URL-encode the key with `encodeURIComponent`.
- **Wait for ready:** Subscribe only after `event: "ready"` arrives.
- **Send JSON text frames:** One JSON object per message; the server does not accept binary frames from clients.
- **Verify symbols and channels:** Take symbols from the asset class's REST list (for example `GET /stocks/symbols`), use market-qualified equities such as `US:KO`, and subscribe only to channels in your package.
- **Stay within limits:** Close unused connections before opening new ones and keep to your distinct-symbol allowance; see [Rate limits](https://tickerlayer.com/docs/limits).

REST errors are covered in [Errors](https://tickerlayer.com/docs/errors).
