Error Response Reference
Every error response in an ergo pipeline uses
RFC 9457 Problem Details format
(Content-Type: application/problem+json). This page is the consolidated
reference for all possible error responses — organized by the pipeline
stage that produces them.
Transport Layer
Section titled “Transport Layer”The transport layer runs before the four-stage pipeline. These responses are produced by the router dispatch logic and transport middleware (request ID, security headers, rate limiting, CORS preflight).
| Status | Source | Condition | RFC |
|---|---|---|---|
| 404 Not Found | Router | No route matches the request path | RFC 9110 §15.5.5 |
| 405 Method Not Allowed | Router | Path exists but method not registered (includes Allow header) |
RFC 9110 §15.5.6 |
| 415 Unsupported Media Type | Router (strictPatch) |
PATCH with Content-Type not in application/json, application/merge-patch+json, application/json-patch+json (includes Accept-Patch header) |
RFC 9110 §15.5.16 |
| 415 Unsupported Media Type | Router (strictBody) |
POST/PUT without Content-Type header |
RFC 9110 §15.5.16 |
| 429 Too Many Requests | Transport rate limit | Request count exceeds transport.rateLimit.max |
RFC 6585 §4 |
| 403 Forbidden | Transport CORS | Preflight OPTIONS request with disallowed origin |
Fetch Standard |
Stage 1: Negotiation
Section titled “Stage 1: Negotiation”Content negotiation middleware runs first — there is no point authenticating or validating a request the server cannot meaningfully respond to.
| Status | Source | Condition | RFC |
|---|---|---|---|
| 403 Forbidden | cors() |
Origin header present but not allowed by policy |
Fetch Standard |
| 406 Not Acceptable | accepts() |
Any negotiated value is undefined and throwIfFail is true |
RFC 9110 §12.5 |
| 428 Precondition Required | precondition() |
Neither If-Match nor If-Unmodified-Since header present |
RFC 6585 §3 |
| 429 Too Many Requests | rateLimit() |
Per-route request count exceeds max within windowMs |
RFC 6585 §4 |
Stage 2: Authorization
Section titled “Stage 2: Authorization”Authentication and authorization middleware rejects unauthorized callers before any request body parsing occurs.
| Status | Source | Condition | RFC |
|---|---|---|---|
| 400 Bad Request | authorization() |
Bearer: authorizer returns info.error: 'invalid_request' |
RFC 6750 §3.1 |
| 401 Unauthorized | authorization() |
Missing or invalid credentials (Bearer default; missing header with configured strategies) | RFC 6750 §3.1 |
| 403 Forbidden | authorization() |
Basic auth failure; Bearer insufficient_scope; no configured strategies; custom scheme rejection |
RFC 6750 §3.1 / RFC 7617 |
| 403 Forbidden | csrf() |
Missing header token, missing UUID cookie, or CSRF token verification fails | OWASP CSRF |
Stage 3: Validation
Section titled “Stage 3: Validation”Input validation middleware parses and validates the request body, query parameters, and idempotency keys.
| Status | Source | Condition | RFC |
|---|---|---|---|
| 400 Bad Request | body() |
Content-Length mismatch, malformed body, or parse failure | RFC 9110 |
| 400 Bad Request | idempotency() |
Idempotency-Key header present but not a valid RFC 8941 sf-string |
RFC 8941 |
| 400 Bad Request | idempotency() |
Idempotency-Key header absent and required: true |
IETF draft |
| 400 Bad Request | jsonApiQuery() |
Query parameters fail JSON:API schema validation | JSON:API |
| 409 Conflict | idempotency() |
Same key with different request fingerprint, or concurrent request still processing | IETF draft |
| 411 Length Required | body() |
Neither Content-Length nor chunked encoding present |
RFC 9110 §15.5.12 |
| 413 Payload Too Large | body() |
Body exceeds limit (or decompressed body exceeds decompressedLimit) |
RFC 9110 §15.5.14 |
| 415 Unsupported Media Type | body() |
Unrecognized content type or unsupported Content-Encoding |
RFC 9110 §15.5.16 |
| 422 Unprocessable Entity | validate() |
JSON Schema validation failure — response includes details array with per-field errors (see Validation Error Response for the full details shape) |
RFC 9110 §15.5.21 |
| 500 Internal Server Error | validate() |
Body schema configured but acc.body is missing — body() middleware not placed before validate() |
— |
Stage 4: Execution / Post-Pipeline
Section titled “Stage 4: Execution / Post-Pipeline”Execution-stage middleware wraps the handler and post-processes the
response. These responses come from timeout(), send() conditional
request evaluation, and uncaught pipeline errors.
| Status | Source | Condition | RFC |
|---|---|---|---|
| 204 No Content | send() |
Prefer: return=minimal on 2xx responses (200 → 204) |
RFC 7240 |
| 304 Not Modified | send() |
If-None-Match weak-matches the ETag, or If-Modified-Since and resource not modified |
RFC 9110 §15.4.5 |
| 408 Request Timeout | timeout() |
Default — deadline exceeded | RFC 9110 §15.5.9 |
| 412 Precondition Failed | send() |
If-Match fails on unsafe methods, or If-Unmodified-Since fails |
RFC 9110 §15.5.13 |
| 500 Internal Server Error | handler() / auto-wrap |
Uncaught pipeline error (detail is redacted for security) | — |
| 504 Gateway Timeout | timeout() |
When configured with statusCode: 504 |
RFC 9110 §15.6.5 |
Further Reading
Section titled “Further Reading”- Fast Fail Pipeline — the four-stage ordering model
- Architecture — the two-accumulator pipeline model
- Error Handling recipe — custom error details, extension members, and RFC 9457 format
- Accumulator Reference — the companion cross-cutting reference for success-path data flow