Reference
Errors
Every error a client, an agent or the dashboard can show you, with its HTTP status, JSON-RPC code, exact text, cause and fix.
This page lists the errors you can run into, grouped by where you meet them: the MCP endpoint your clients call, the agent endpoints your SDK calls, tool call results, OAuth, the dashboard, and webhook deliveries. Messages are copied from the service. Where a message contains a value it is shown in angle brackets. For a walk-through by symptom, see Troubleshooting.
#How errors are shaped
| Surface | Shape |
|---|
Agent endpoints (/agent/*), and the checks that run before a request reaches the MCP engine | { "error": "<message>" } |
| The MCP endpoint once a request is past authentication | JSON-RPC 2.0: { "jsonrpc": "2.0", "id": <id or null>, "error": { "code": <int>, "message": <string> } } |
| A tool that fails | Not an error response: a successful JSON-RPC result with isError: true. See Tool call outcomes |
| OAuth failures on the MCP endpoint | { "error": "<oauth code>", "error_description": "<text>" } with a WWW-Authenticate header |
| Dashboard pages | An HTML error page. Forms show the message from the service |
Every 401 carries a WWW-Authenticate challenge. Every 429 from a rate limit carries Retry-After, in seconds.
#JSON-RPC codes at a glance
| Code | HTTP | Meaning |
|---|
-32600 | 400 | Invalid request: not a JSON-RPC message |
-32601 | 200 | Method not found (a list with nothing in it is an empty list, not this error) |
-32602 | 200 | Invalid params: unknown tool, unknown resource, bad prompt arguments, bad tools/call params |
-32603 | 200 | Internal error: a resource read or prompt render failed. The message is your agent's, or the timeout text |
-32000 | 400, 405, 406, 415 | Transport-level refusal: missing Accept, wrong method, wrong content type, unsupported protocol version |
-32001 | 503 | No agent connected, or every agent disabled |
-32002 | 429 | Monthly allowance used up |
-32003 | 403 | Project or account suspended |
-32004 | 403 | Caller address not on the project's client allow-list |
-32001 to -32004 are this service's own codes.
#General errors
These can come from any route.
| Status | Body | Cause | Fix |
|---|
503 | {"error":"Service is shutting down."} | The gateway is restarting and refusing new work while running calls finish | Retry. The SDKs reconnect by themselves |
400 | {"error":"<parser message>"}, for example Unexpected token 'n', "not json" is not valid JSON | The body is not valid JSON on a route that reads JSON | Send valid JSON with Content-Type: application/json |
413 | {"error":"request entity too large"} | Body over the limit: 512 KB on /agent/connect, 4 MB elsewhere | Send less |
500 | {"error":"Internal error."} | An unexpected failure on our side | Retry, and if it persists contact us with the time and the request |
404 | {"error":"Not found."} | A path that does not exist | Use a documented path |
#API-key authentication
For /agent/connect, /agent/result, /agent/telemetry (an agent or full key) and /mcp/<project-id> (a client or full key).
| Status | Body | Cause | Fix |
|---|
401 | {"error":"Missing API key."}, header WWW-Authenticate: Bearer realm="mcp" | No Authorization header | Send Authorization: Bearer <key>. For an SDK, SPACEFIX_API_KEY is not set |
401 | {"error":"Invalid API key."}, header WWW-Authenticate: Bearer realm="mcp", error="invalid_token", error_description="Invalid API key." | The key is unknown, revoked or expired, or it was truncated or has a stray space | Create a new key on the project page. Revoked and expired keys cannot be restored. Use Check connection with the pasted key to see which |
403 | {"error":"This is a client key. Agents connect with an agent key."} | A client key was used on an agent endpoint | Use an agent or full key in the SDK |
403 | {"error":"This is an agent key. MCP clients connect with a client key."} | An agent key was used on the MCP endpoint | Use a client or full key in the MCP client |
429 | {"error":"Too many failed authentication attempts."} | More than 30 rejected keys a minute from one address. A valid key is never counted | Stop retrying the bad key (a stale key in a restart loop is the usual cause), fix it, and wait for Retry-After |
#MCP endpoint errors
POST /mcp/<project-id>, in the order the checks run. The endpoint is described in MCP endpoint.
| Status | JSON-RPC | Message | Cause | Fix |
|---|
401, 403, 429 | none | See API-key authentication | | |
400 | none | The JSON parser's message | The body is not valid JSON | Send valid JSON |
413 | none | request entity too large | The body is over 4 MB | Send less |
403 | -32003 | This project is suspended: <reason> | The project or its account is suspended | Contact us. The dashboard shows the reason |
403 | -32004 | This address is not on the project's client allow-list. | The project has an Allowed client addresses list and the caller's address is outside it | Add the address or range in Project settings. A client behind a proxy presents the proxy's address |
429 | none | Rate limit exceeded: <n> requests per minute. | More than the plan's requests per minute for the project (Free 600). Every client of the project shares the budget | Wait Retry-After seconds, send fewer requests, or use a larger plan |
403 | none | Forbidden - agent identity mismatch. | The key (or OAuth token) belongs to a different project than the URL | Use the right project id in the URL, or the right key |
429 | -32002 | Monthly allowance of <n> calls on the <Plan> plan is used up. It resets on the 1st (UTC), or upgrade the plan. | Free plan, allowance spent. Applies to tools/call, resources/read and prompts/get only | Wait for the 1st (UTC), or ask us for a larger plan. tools/list still works |
503 | -32001 | No agent connected for server "<id>". | No agent is connected for the project | Start the agent. Check SPACEFIX_API_KEY and SPACEFIX_SERVICE_URL. Use Check connection |
503 | -32001 | Every agent for server "<id>" is disabled. | Agents are connected but all were disabled on the Agents page | Enable one. A disable lasts only as long as the connection |
406 | -32000 | Not Acceptable: Client must accept both application/json and text/event-stream | Accept lacks one of the two types | Send Accept: application/json, text/event-stream |
415 | -32000 | Unsupported Media Type: Content-Type must be application/json | Wrong Content-Type on a POST | Send application/json |
405 | -32000 | Method not allowed. | GET, DELETE and the rest: the endpoint only accepts POST | Use POST. A client that tries to open a GET stream may ignore this 405 |
400 | -32000 | Bad Request: Unsupported protocol version: <v> (supported versions: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07) | MCP-Protocol-Version names an unknown revision | Use a supported version |
400 | -32600 | Bad Request: the request body is not a valid JSON-RPC message | Valid JSON that is not a JSON-RPC request, for example {"foo":1} | Send jsonrpc, id and method |
200 | -32601 | Method not found | A method the endpoint does not implement (logging/setLevel, completion/complete, resources/subscribe) | Do not call it |
200 | -32602 | Tool <name> not found | The tool is not registered, is disabled by you, is outside the key's allow-list, or does not read and the caller is read-only (a read-only key, Client access set to Read only, or an mcp:read token) | Check tools/list for that key. Enable the tool, widen the allow-list, or label the tool readOnlyHint: true (or mark it Read under Tools) if it only reads |
200 | -32602 | Resource not found: <uri>, with data: {"uri":"<uri>"} | No registered resource has that uri | Use a uri from resources/list |
200 | -32602 | Invalid arguments for prompt <name>: <details> | A required prompt argument is missing | Send it |
200 | -32602 | Invalid tools/call request: <details> | params or arguments has the wrong type, for example arguments is a string | Send arguments as an object |
200 | -32603 | Your agent's error text, or Request for resource "<uri>" timed out after <ms>ms. / Request for prompt "<name>" timed out after <ms>ms. | A resource read or prompt render failed or timed out on the agent | Fix the handler, or raise the project's call timeout |
A tools/call that reaches your agent and fails comes back as HTTP 200 with a result of { "content": [ { "type": "text", "text": "<message>" } ], "isError": true }, so the model can see it. The message is also written to the call log (first 300 characters), and Logs classes it as a failure type: Timed out when it contains timed out after, No agent connected when it starts with No connected agent or Every connected agent, and Agent error otherwise.
Message (the text) | Cause | Fix |
|---|
Input validation error: Invalid arguments for tool <name>: <details> | The arguments do not match the schema your agent registered. The call never reaches your agent and is not counted | Fix the call. If a schema has an argument named format or pattern, rename it |
Request for tool "<name>" timed out after <ms>ms. | Your agent did not answer within the project's call timeout (30 seconds by default). A late result is dropped. The call is counted | Make the handler faster, or raise the project's timeout up to 30 seconds |
Agent disconnected before returning a result. | The agent process, its network, or a proxy dropped the stream while the call was running | Check the agent's logs and idle timeouts along the path |
Key revoked. | The key the agent connected with was revoked, and its stream was closed | Create a new key and redeploy the agent |
Key rotated. | The project's full keys were rotated | Use the new key |
Project deleted. / Account deleted. | The project or account was deleted | n/a |
Project suspended. / Account suspended. | The project or account was suspended | Contact us |
Service is shutting down. | The gateway is restarting | Retry. The SDK reconnects |
No connected agent serves tool "<name>". | At the moment of dispatch no enabled agent had that tool. Also seen as ... resource "<uri>" and ... prompt "<name>". Logged, but not counted | Wait for the agent to reconnect |
Every connected agent for this project is disabled. | Every agent was disabled between the checks and dispatch | Enable one |
Tool failed. | Your agent reported a failure with no message | Return an error message from the handler |
| Your own error text | Your tool threw or returned an error | Fix the tool |
#Agent endpoint errors
/agent/connect, /agent/result and /agent/telemetry. The wire protocol is in Agent protocol. After the key checks above:
| Route | Status | Body | Cause | Fix |
|---|
| any | 415 | {"error":"Content-Type must be application/json."} | The request has no JSON content type | Send Content-Type: application/json |
/agent/connect | 403 | {"jsonrpc":"2.0","id":null,"error":{"code":-32003,"message":"This project is suspended: <reason>"}} | The project or its account is suspended. The body is JSON-RPC shaped even though this is not an MCP call | Contact us |
/agent/connect | 429 | {"error":"Rate limit exceeded: <n> requests per minute."} | More than the plan's connection attempts a minute for the project (Free 60). A reconnect loop is the usual cause | Back off. Find why the agent keeps reconnecting. Honour Retry-After |
/agent/connect | 400 | {"error":"\"tools\" must be an array."} | The body has no tools array. It is required, even if empty | Send tools: [] at minimum |
/agent/connect | 400 | {"error":"\"resources\" must be an array."} / {"error":"\"prompts\" must be an array."} | Sent, but not an array | Fix the type |
/agent/connect | 400 | {"error":"Invalid prompt <json name>."} | A prompt name outside letters, digits, _, - (1 to 64 characters), or arguments that is not an array | Rename or fix the prompt |
/agent/connect | 400 | {"error":"Invalid resource <json uri>."} | A resource that is not an object, or has a missing, empty or over-long (more than 2,048 characters) uri | Fix the resource |
/agent/connect | 400 | {"error":"Invalid name for resource \"<uri>\"."} | A resource name that is not a string | Send a string |
/agent/connect | 400 | {"error":"Duplicate resource \"<uri>\"."} | Two resources share a uri | Make them unique |
/agent/connect | 400 | {"error":"Too many resources: limit is 1000."} | More than 1,000 resources | Register fewer |
/agent/connect | 400 | {"error":"Too many tools: limit is <n>."} | More tools than the plan's limit (Free 256) | Register fewer |
/agent/connect | 400 | {"error":"Invalid tool name <json name>."} | A tool name outside letters, digits, _, - (1 to 64 characters). A . or a space is invalid | Rename the tool |
/agent/connect | 400 | {"error":"Schema for \"<name>\" exceeds <n> bytes."} | The tool's inputSchema is larger than the plan's limit (Free 65,536 bytes) | Simplify the schema |
/agent/connect | 400 | {"error":"Schema for \"<name>\" is not valid JSON Schema: <detail>"} | The schema does not compile, for example type must be JSONType or JSONType[]: nonsense | Fix the schema |
/agent/connect | 429 | {"error":"Too many agent connections: the <Plan> plan allows <n>."} | The project already has the plan's maximum number of open agent streams (Free 32) | Close idle agents, run fewer replicas, or use a larger plan |
/agent/connect | 413 | {"error":"request entity too large"} | Registration over 512 KB | Register fewer or smaller schemas |
/agent/result | 413 | same | Result over 4 MB. The call then times out | Return less data |
/agent/result | 204 | none | Not an error. An unknown, late or foreign connection or call id is silently dropped | |
/agent/telemetry | 204 | none | Always, once the key and content type pass, even for an empty or malformed body | |
#OAuth errors
Only where OAuth is turned on for your deployment. The body is { "error": "<code>", "error_description": "<text>" } and the header is WWW-Authenticate: Bearer error="<code>", error_description="<text>", ....
| Status | error | error_description | Cause | Fix |
|---|
401 | invalid_token | Missing Authorization header | No header. This is the first step of the client's sign-in discovery, not a fault | Let the client run its OAuth flow |
401 | invalid_token | Invalid Authorization header format, expected 'Bearer TOKEN' | Not a bearer header | Send Authorization: Bearer <token> |
401 | invalid_token | The verifier's message (signature, issuer, audience or expiry) | The token failed verification: wrong issuer, wrong audience, expired, or signed by another key | Get a fresh token from the right identity provider |
401 | invalid_token | Token has no "server_id" claim. | The access token does not name a project | The identity provider must add the claim |
401 | invalid_token | Token has no expiration time / Token has expired | Missing or past exp | Refresh the token |
403 | insufficient_scope | The token needs one of these scopes: mcp:write, mcp:invoke, mcp:read. (with the defaults) | The token has none of the accepted scopes. Any one is enough: a write scope reads and writes, mcp:read reads only | Request mcp:write, or mcp:read for read-only use |
403 | none | {"error":"Forbidden - agent identity mismatch."} | The token's project is not the one in the URL | Get a token for that project |
500 | server_error | Internal Server Error | Verification failed for a reason other than the token, for example the identity provider is unreachable | Contact us |
503 | none | {"error":"Authorization Server metadata is unavailable."} | The sign-in discovery document could not be fetched | Contact us |
#Dashboard errors
These are the messages the dashboard shows in forms and dialogs.
#Everywhere
| Status | Message | Cause | Fix |
|---|
401 | Not signed in. | No session, or it expired or was revoked | Sign in again |
403 | Cross-site request refused. | A change request without the X-Requested-With header, or from another site | Only the dashboard's own pages may change things. A script must send that header and the session cookie |
403 | Confirm your email address first. We sent a link when you signed up; you can ask for another in the banner. (code email_unverified) | Creating a project or key before confirming your email, where verification is required | Open the link, or press Resend link |
429 | Too many attempts. Try again in a minute. | The per-address limit on sign-in and similar routes (20 a minute) | Wait for Retry-After |
404 | No such project. | The project id is unknown or belongs to another account | Check the id |
502 | The service is unreachable. Try again in a moment. | The dashboard could not reach the service, or it did not answer in time | Retry |
| any | An error page reading Page not found, or Something went wrong | No such page, or an unexpected failure | Retry. If it persists, contact us |
404 | Trace not found. It may be older than your plan keeps history. | A trace id that is unknown or older than your log retention | Check the id and your plan's history |
#Sign-up, sign-in and credentials
| Where | Message | Cause | Fix |
|---|
| Sign-up | A valid email and a password of 8 to 1024 characters. | The email has no @, or the password is too short or too long | Fix it |
| Sign-up | Accept the Terms of Service and Privacy Policy to create an account. | The box is not ticked | Tick it |
| Sign-up | That email is already registered. | Duplicate address | Sign in or reset the password |
| Sign-up | Too many accounts created from this address today. Try again tomorrow. | More than 10 sign-ups from one address in a UTC day | Try tomorrow |
| Sign-in | Incorrect email or password. | Unknown email or wrong password (indistinguishable on purpose) | Check both, or reset the password |
| Sign-in | Enter the 6-digit code from your authenticator app, or a recovery code. | Two-factor is on and no code was sent | Enter the code |
| Sign-in | That code is not right. | A wrong, expired or already-used code | Use the next code, and check your phone's clock |
| Sign-in | Too many attempts. Wait a minute and try again. | 5 code guesses a minute per account | Wait |
| Sign-in | Two-factor sign-in is unavailable right now. ... | We cannot read your second factor at the moment. The message goes on to name a server setting | Contact us |
| Verification link | A link was just sent. Give it a minute, then try again. | A link was sent less than 60 seconds ago | Wait a minute |
| Verification, reset and email-change links | That link has expired or was already used. | Expired (verification and email change 24 hours, password reset 1 hour), already used, replaced by a newer one, or the email changed since | Request another link |
| Reset password | Password must be 8 to 1024 characters. | Checked before the link is spent | Choose another |
| Confirm email change | That email is already registered. | Someone registered the new address in the meantime | Choose another |
| Settings | A valid email. | The new address has no @ | Fix it |
| Settings | Unknown brand colour. | Not one of the offered colours | Pick one |
| Settings | "off" is a list of: offline, allowance, expiry. | A bad notification setting | Use the toggles |
| Change password | Current password is incorrect. | | Retry |
| Change password | New password must be 8 to 1024 characters. | | Choose another |
| Delete account | Password is incorrect. | | Retry |
| Delete account | Type your email address to confirm. | The typed address is not your account's | Type it exactly |
#Two-factor and devices
| Message | Cause |
|---|
Two-factor authentication is already on. | You tried to set it up again |
Start setup first. | No setup is pending |
That code is not right. Check the time on your phone and try the next one. | The code did not match. One 30-second step either side is accepted |
That code is not right. | A wrong code when turning it off |
Password is incorrect. | A wrong password when turning it off |
Too many attempts. Wait a minute. | The second-factor limit |
No such session. | The device you tried to sign out is already gone |
| Message | Cause | Fix |
|---|
A project name is required. | Missing or blank name | Enter one |
The <Plan> plan is limited to <n> projects. (code plan_limit) | At the plan's project limit (Free 5) | Delete one, or ask for a larger plan |
A name of 1 to 60 characters. | Renaming a project | Shorten it |
The call timeout is a whole number of seconds from 1 to <n>. | n is 30 | Enter a whole number from 1 to 30 |
Up to 20 IP addresses or CIDR ranges, such as 203.0.113.7 or 10.0.0.0/8. | A bad entry, or more than 20 | Fix the list |
A label of 1 to 60 characters is required. | Creating a key | Enter a label |
Key type must be agent, client or full. | | Pick a type |
Expiry must be between 1 and 365 days. | | Pick an expiry |
A tool allow-list applies to client and full keys. | You gave an Agent key an allow-list | Remove the list, or use a client or full key |
Access must be "read" or "write". | Creating a key with another Access value | Pick Read and write or Read only |
Read-only access applies to client and full keys. | You made an Agent key read-only | Leave Access off, or use a client or full key |
Tool patterns are up to 50 names of letters, digits, "_", "-" and "*". | More than 50 patterns, one over 64 characters, or an illegal character | Fix the patterns |
The <Plan> plan is limited to <n> active keys per project. (code plan_limit) | At the plan's key limit (Free 10) | Revoke a key |
No such key. | The key is not an active key of this project | Reload |
Not a valid tool name. | A tool-settings name outside letters, digits, _, ., :, - (1 to 128 characters) | Check the name |
"disabled" must be true or false. | | Use the switch |
A description is text of up to 1000 characters. | | Shorten it |
Cache time is a whole number of seconds from 0 (off) to 3600. | | Fix it |
Access must be "read", "write", or empty to follow the agent. | Saving a tool's Reads or writes with another value | Pick one of the options |
Client access must be "read" or "write". | Saving Client access in Project settings with another value | Pick Read and write or Read only |
Too many tool overrides. (code plan_limit) | 256 tools already have saved settings | Clear some |
#Agents
| Message | Cause |
|---|
` disabled must be true or false. ` | A bad value sent when disabling or enabling an agent |
No such agent. It may have disconnected. | An agent's id exists only while it is connected |
#Logs, Traces, Usage and exports
| Message | Cause | Fix |
|---|
No such trace. | A malformed id (not 32 hex characters), no calls with it within your retention, or it is not yours | Check the id |
Too many exports. Try again in a minute. | More than 6 exports a minute per account | Wait |
Use from and to as YYYY-MM-DD, at most a year apart. | A bad date, from after to, or a span over a year | Fix the range |
#Webhooks
| Message | Cause |
|---|
A URL is required. | No URL |
Not a valid URL. | It cannot be parsed |
The URL is too long. | Over 500 characters |
Put credentials in the signature check, not the URL. | The URL has a username or password |
The URL must start with https://. | Plain http:// |
That address is not reachable from the internet. | A private, loopback, link-local or reserved address |
That host is not reachable from the internet. | localhost, *.localhost or *.internal |
Events are any of: agent.connected, agent.disconnected, key.created, key.revoked, allowance.warning, allowance.exceeded. | An unknown event, or ping |
At most 5 webhooks per account. (code plan_limit) | The limit |
No such webhook. | Deleting, testing or re-enabling one that is gone |
#Playground
| Status | Message | Cause | Fix |
|---|
429 | Too many test calls. Try again in a minute. | More than 30 runs a minute per account | Wait |
404 | That tool is not registered right now. | No agent has it | Connect the agent |
403 | That tool is disabled. Enable it to try it. | You disabled it | Enable it |
400 | Arguments must be a JSON object. | The arguments are an array, string or null | Send an object |
422 | The arguments do not match the tool's schema., with the reasons listed | Schema validation failed | Fix the arguments |
429 | The playground allows <n> runs a week and they are used up. It resets <YYYY-MM-DD HH:MM> UTC. (code playground_limit) | The weekly allowance (10 on Free) is spent | Wait for the reset time |
A Playground tool that fails is not an HTTP error: the run completes and the result shows the error your handler returned.
#Webhook delivery errors
These are not HTTP responses. They are shown on the Webhooks page as the webhook's last delivery. A delivery fails when it does not get a 2xx.
| Last delivery | Cause |
|---|
failed (<status>), for example failed (405) | Your endpoint answered a non-2xx status. A 4xx other than 429 is not retried. 5xx and 429 are retried after 10 seconds and 2 minutes |
failed: Timed out. | No response within 5 seconds |
failed: Resolved to a private address. | The name resolved to a private, loopback or link-local address |
failed: Not a valid URL., The URL must start with https://., That address is not reachable from the internet., That host is not reachable from the internet., The URL is too long., Put credentials in the signature check, not the URL. | The stored URL no longer passes the checks |
failed: <network error>, for example getaddrinfo ENOTFOUND ... or connect ECONNREFUSED ... | A network failure (first 200 characters of the error) |
After 20 deliveries in a row fail, the webhook is switched off until you press Re-enable. See Alerts and webhooks.
#Next steps