Skip to content

Latest commit

 

History

History
132 lines (96 loc) · 7.02 KB

File metadata and controls

132 lines (96 loc) · 7.02 KB

Response Codes and Headers

The proxy returns its own status codes for queue and validation errors, and passes backend codes through for successful responses. Understanding which codes originate from the proxy vs. the backend helps diagnose issues quickly.

TL;DR

  • 429 — the proxy itself is at capacity (queue full, all circuits open, no active hosts).
  • 412 — the request waited too long in the queue and its TTL expired before being sent.
  • 503 — no host was attempted, or name-resolution/connection failures exhausted the available hosts.

Proxy-Originated Response Codes

These codes are generated by the proxy itself, never passed from a backend.

Code Name Proxy cause
400 Bad Request Malformed S7PTTL header value (InvalidTTL)
403 Forbidden App ID validation failed (DisallowedAppID); inbound key validation failed (DisallowedKey); user not found in profile or suspended (UnknownProfile)
408 Request Timeout IO exception or task cancellation while communicating with backend
412 Precondition Failed Request TTL expired while waiting in queue (TTLExpired) — ExpiresAt passed before dispatch
417 Expectation Failed Required header missing (IncompleteHeaders); header validation rule failed (InvalidHeader)
429 Too Many Requests Queue full; backend circuit check failed; no active hosts; or max undrained events exceeded
500 Internal Server Error Unhandled exception; request body too large to buffer (OOM → ContentTooLarge)
502 Bad Gateway Backend attempts failed with different status codes, or an unclassified transport error occurred
503 Service Unavailable No host was attempted, or backend name-resolution/connection failures exhausted the available hosts

Note

Proxy-originated 429 responses include a Retry-After header: the configured poll interval when no active hosts are available, otherwise 500 (ms). Probe requests are exempt from every admission check that produces these codes.


Backend Pass-Through Codes

Any status code the proxy receives from a backend that is in AcceptableStatusCodes is forwarded directly to the client without triggering a retry.

Default AcceptableStatusCodes: 200, 202, 401, 403, 404, 408, 410, 412, 417, 400

Codes not in this list (for example, 500, 502, or 503) cause the proxy to advance to the next backend. Any code in the list, including 404, is returned directly without retry or circuit recording.

Tip

To pass 503 through from a backend instead of retrying, add it to AcceptableStatusCodes.


Backend 429 and Requeue

When a backend returns 429:

S7PREQUEUE header on response Proxy behaviour
true Record the request as eligible for delayed requeue, then continue trying available hosts
absent / not true Proxy tries the next backend host

After host attempts are exhausted, the proxy requeues if at least one backend returned 429 with S7PREQUEUE: true. It uses the shortest eligible delay from retry-after-ms (milliseconds) or Retry-After (seconds), defaulting to 1000 ms.


Request Headers (proxy reads these)

Header Description
S7PDEBUG Set to true to enable per-request debug tracing in logs
S7PPriorityKey Looked up in PriorityKeys; matching entry sets the request priority from PriorityValues. Header name is configurable via PriorityKeyHeader
S7PTTL Time-to-live for the request (seconds). Expired requests return 412. Default TTL is DefaultTTLSecs (300 s)
S7PTimeout Per-request timeout override (ms). Header name is configurable via TimeoutHeader
S7P-Iterator Per-request iteration mode override: SinglePass or MultiPass (case-insensitive). Missing or invalid values use the current IterationMode default
S7PREQUEUE Set by a backend on a 429 response to trigger requeue with retry-after logic

Response Headers (proxy adds these)

These headers are injected by the proxy on every successful proxied response.

Header Description
Request-Queue-Duration Milliseconds the request spent in the priority queue
Request-Process-Duration Milliseconds spent in the proxy worker (dequeue → response write)
BackendHost Hostname of the backend that served the response
Total-Latency Total milliseconds from enqueue to response (queue + process)
Attempts Backend attempts made during the current dispatch cycle
Lifetime-Attempts Cumulative backend attempts across all requeue cycles

Note

Exhausted-host error responses use x-Request-Queue-Duration, x-Total-Latency, x-ProxyHost, and x-MID. Async 202 responses include x-Data-Blob-URI and x-Header-Blob-URI.


Health Probe Endpoints

Note

Health probe endpoints are served on the main application port by default. Port 9000 is only used when the optional sidecar is enabled (see HEALTH_CHECKING.md).

Path Returns
/liveness 200 when the process is running; never returns 503
/readiness 200 when startup, active-host, event-backlog, and blob-queue criteria pass; 503 otherwise
/startup 200 when initialization and readiness health criteria pass; 503 otherwise

Diagnostic Flow

Client request arrives
        │
        ├── TTL already expired?  ──► 412 Precondition Failed
        ├── Validation failed?    ──► 403 Forbidden / 417 Expectation Failed
        ├── Queue full / CB open / no hosts? ──► 429 Too Many Requests
        │
        └── Enqueued → Worker picks up
                │
                ├── TTL expired in queue? ──► 412
                │
                └── Send to backend (try each active host)
                        │
                        ├── Backend: AcceptableStatusCode ────────────► pass-through to client
                        ├── Backend: non-acceptable status ───────────► skip, try next host
                        ├── Backend: 429 + S7PREQUEUE=true ───────────► collect; requeue after attempts exhaust
                        ├── Backend: 429 (no requeue) ────────────────► skip, try next host
                        └── Attempts exhausted ───────────────────────► 502 or 503 by failure type

Related Documentation