Timeouts Reference

Vrata has timeouts at three levels. All use semantic names and Go duration strings (5s, 100ms, 2m30s).

Listener timeouts

How long the listener waits for the client. Configured on the listener entity via the API.

FieldGo fieldDefaultWhat happens when it fires
clientHeaderReadHeaderTimeout10sClient too slow sending headers → connection closed
clientRequestReadTimeout60sClient too slow sending body → connection closed
clientResponseWriteTimeout60sResponse too slow to write → connection closed
idleBetweenRequestsIdleTimeout120sNo new request on keep-alive → connection closed

Destination timeouts

How long each stage of the upstream connection takes. Configured on the destination entity via the API.

FieldGo fieldDefaultWhat happens when it fires
requestClient.Timeout30sTotal call exceeded → structured error (502)
connectDialer.Timeout5sTCP connect failed → connection_refused
dualStackFallbackDialer.FallbackDelay300msTry other IP family (IPv4↔IPv6)
tlsHandshakeTLSHandshakeTimeout5sTLS failed → tls_handshake_failure
responseHeaderResponseHeaderTimeout10sUpstream accepted but won’t respond → timeout
expectContinueExpectContinueTimeout1sNo 100-Continue → send body anyway
idleConnectionIdleConnTimeout90sIdle pool connection → closed

Route timeouts

The outermost watchdog — if the total time exceeds this, Vrata cuts the request. Configured on the route entity via the API.

FieldDefaultDescription
forward.timeouts.requestTotal request deadline (wraps everything)

If the route doesn’t set this, Vrata falls back to destination.options.timeouts.request. The most restrictive always wins.

Middleware timeouts

MiddlewareFieldDefaultDescription
ExtAuthzdecisionTimeout5sTotal time for auth decision
ExtProcphaseTimeout200msTime per processing phase
JWTjwksRetrievalTimeout10sTime to download JWKS

How they interact

Client ──── Listener ──── Vrata ──── Destination ──── Upstream

  clientHeader ──────────┐
  clientRequest ─────────┤ listener
  clientResponse ────────┤
  idleBetweenRequests ───┘
                       forward.timeouts.request (route watchdog)
                              ├─ request ──────────────┐
                              ├─ connect               │
                              ├─ tlsHandshake          ├─ destination
                              ├─ responseHeader        │
                              └─ idleConnection ───────┘

The most restrictive timeout always wins. A responseHeader: 10s on the destination fires before forward.timeouts.request: 30s on the route if the upstream takes 11 seconds to start responding.