Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Fault injection

Two request headers turn any route into a misbehaving upstream, so retry, timeout, circuit breaker and failover policies can be shown against the endpoint you were already demoing. They work on every route except the control plane (/_rustybin/*) and the web console (/ui/*).

HeaderEffect
X-Rustybin-Delay: <ms>Wait that many milliseconds before handling the request (capped at 30000, 10000 in public mode).
X-Rustybin-Fail: <status>Answer with that status (400 to 599) and a JSON error body instead of calling the route.
X-Rustybin-Fail: <status>:<percent>The same with a probability: 503:50 fails about half of the requests (503:50% works too).

Responses that were affected carry X-Rustybin-Fault: fail or X-Rustybin-Fault: delay. Values that do not parse (a status outside 400 to 599, a percent above 100, a negative delay) are ignored and the request is served normally.

GET {{base_url}}/echo
X-Rustybin-Fail: 503
HTTP 503
[Asserts]
header "X-Rustybin-Fault" == "fail"
jsonpath "$.error" == "injected fault"
jsonpath "$.status" == 503
jsonpath "$.percent" == 100
jsonpath "$.injected_by" == "X-Rustybin-Fail"
# 0 percent never fails; 503:50 fails about half of the requests.
GET {{base_url}}/echo
X-Rustybin-Fail: 503:0
HTTP 200
POST {{base_url}}/anything/orders
X-Rustybin-Delay: 300
Content-Type: application/json
{"id": 1}
HTTP 200
[Asserts]
header "X-Rustybin-Fault" == "delay"
duration >= 300

Both headers combine: the delay happens first, then the fault.

GET {{base_url}}/status/200
X-Rustybin-Delay: 200
X-Rustybin-Fail: 504
HTTP 504
[Asserts]
duration >= 200
# Values that do not parse are ignored (the request is served normally).
GET {{base_url}}/echo
X-Rustybin-Fail: 200
HTTP 200
GET {{base_url}}/_rustybin/version
X-Rustybin-Fail: 500
HTTP 200
[Asserts]
jsonpath "$.name" == "rustybin"

On the mock LLM

On /ai/* the delay header works as above, but X-Rustybin-Fail is answered by the mock LLM itself, in the provider's native error format (an OpenAI rate_limit_exceeded body with x-ratelimit-* headers, an Anthropic 529 overloaded_error, a Gemini RESOURCE_EXHAUSTED, ...), and accepts symbolic kinds such as rate_limit, overloaded, context_length or content_filter. The mock LLM also has X-Rustybin-Latency-Ms, X-Rustybin-TTFT-Ms and X-Rustybin-Tokens-Per-Second. See Faults, latency, credentials, inspection.

Other chaos tools

ToolUse it for
/status/{code}A fixed or weighted random status (/status/200:0.9,503:0.1)
/delay/{duration}A slow endpoint (up to 60 s) without custom headers
/dripA slow body after fast headers (streaming timeouts)
/flaky/*Deterministic failure patterns per client: fail after n, recover after n, SSF patterns
/health/unhealthyActive health checks and failover (the gRPC health service follows it)
gRPC FailAny gRPC status with rich error details
RUSTYBIN_REQUEST_TIMEOUTThe server's own time-to-headers timeout (503)