Errors
ReferenceDevelopersSince version 0.1.0
On this page
A refusal always carries a stable
codeto switch on. The samecodecrosses REST, gRPC, MCP and the asynchronous channels.Product side: API gateway; operations side: Troubleshooting.
The format
{
"type": "https://flexway.dev/problems/upstream_timeout",
"title": "The upstream did not answer within its budget",
"status": 504,
"detail": "Operation getOrder exceeded its 2s budget.",
"instance": "/orders/42",
"code": "upstream_timeout",
"request_id": "01J9Z2K7QWE",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}Switch on code (or on type, which the operator may redirect to its portal), never on title or
detail. An error never holds the API's internal message, a host name or personal data.
The codes
| Status | code |
Who acts |
|---|---|---|
400 |
malformed_request |
You: unreadable request or undeclared parameter |
401 |
unauthenticated |
You: credential missing or invalid |
403 |
forbidden |
You: scope, role or tenant insufficient |
404 |
not_found |
You: undeclared route |
405 |
method_not_allowed |
You: see Allow |
412 |
precondition_failed |
You: If-Match not met, or SSE resumption beyond the history |
413 |
payload_too_large |
You |
415 |
unsupported_media_type |
You: see Accept |
422 |
invalid_request |
You: see errors |
428 |
idempotency_key_required |
You: add Idempotency-Key |
429 |
rate_limited |
You: slow down, see Retry-After |
429 |
quota_exceeded |
You: the daily or monthly quota is spent |
500 |
internal_error |
The gateway |
502 |
upstream_error |
The API |
502 |
response_too_large |
The API |
503 |
upstream_unavailable |
The API: retry after Retry-After |
503 |
overloaded |
The platform: retry after Retry-After |
504 |
upstream_timeout |
The API: unknown outcome for a write |
| per the API | upstream_status |
The API: an error of a gRPC upstream, or a status the operator translated |
400 says "I could not read it", 422 "I read it, and it is wrong"; 429 is your rate, 503
our capacity; 502 an unusable answer, 504 no answer in time.
On the other surfaces
| Surface | Representation |
|---|---|
/v1/* (inference) |
OpenAI's envelope: unauthenticated -> authentication_error, forbidden -> permission_error, rate_limited -> rate_limit_error, invalid_request -> invalid_request_error; the gateway's code is kept (inference) |
| gRPC | google.rpc.Status, ErrorInfo.reason = the code (gRPC) |
| MCP | An isError result carrying the problem (MCP) |
| SSE, WebSocket | event: error or a last message, then the close (asynchronous channels) |