Skip to content

Error handling

How Dwara formats errors for clients and classifies upstream failures.

Unified error envelope

All gateway-generated error responses use a unified JSON envelope so clients can parse errors programmatically without guessing the body shape:

json
{
  "error": {
    "code": "<machine-code>",
    "message": "<human-readable>",
    "request_id": "<request-id>"
  }
}

The code field is a stable machine-readable string; the message is classification-only text that never leaks upstream internals. The request_id matches the X-Request-Id response header and the access log entry, so an operator can trace any error end-to-end.

Gateway-generated errors

StatusCodeWhen
400bad_requestFraming ambiguity, GraphQL rejection, request validation failure
401unauthorizedNo valid credential found; includes WWW-Authenticate
403forbiddenAuthorization denial, WAF filter, anomaly score, WebSocket origin
404no_routeNo route matched (after listener/global rate limiting)
405method_not_allowedMethod not in the route's methods allowlist
413request_too_largeRoute body cap exceeded
429rate_limit_exceededRate limit or consumer quota; includes Retry-After and X-RateLimit-*
431request_header_fields_too_largeRoute header count/bytes cap exceeded
502upstream_unavailableEndpoint refused, pool failure, no endpoints, pending cap
503upstream_circuit_openCircuit breaker open; includes Retry-After
503service_unavailableGateway concurrency cap / load shedding
504upstream_timeoutConnect or per-attempt read timeout

Upstream error classification

Upstream failure details are logged server-side only; the client sees a classified status with no upstream internals:

CauseStatus
Connect timeout / per-attempt read timeout504
Endpoint refused / pool failure / no endpoints502
Invalid upstream TLS configuration500

A mid-body abort (the upstream connection dies partway through a response body already streaming to the client) is different: the attempt already resolved its headers, so it is final — not retryable — and any bytes already forwarded to the client end abruptly with no synthesized tail (HTTP/1.1 truncation semantics). It is still reported as a passive-health failure for the endpoint, so a chronically flaky-mid-stream endpoint still gets ejected.

See also

  • Request pipeline — where each error status is produced in the pipeline.
  • Observability — access logs, metrics, and tracing for error diagnosis.
  • Traffic policy — retries, circuit breaking, and load shedding that produce 502/503/504.