What Is Saboteur?
Saboteur is a Go-based HTTP-layer fault injection proxy built by Vadim Semenykv that intercepts requests, evaluates rule matches on path, methods, headers, and query params, and injects latency, errors, aborts, throttling, body corruption, or header changes for backend developers, SREs, QA engineers, and platform teams. Saboteur is one of the best HTTP Fault Injection Proxies tools for backend developers, SREs, QA engineers, and platform teams. It ships 7 fault types, a control API on port 8081, and a live traffic log so teams can verify failure behavior without guessing.
Quick Overview
| Attribute | Details |
|---|---|
| Type | HTTP Fault Injection Proxies |
| Best For | backend developers, SREs, QA engineers, and platform teams |
| Language/Stack | Go, Docker, YAML, REST API, Prometheus, Server-Sent Events |
| License | N/A |
| GitHub Stars | N/A as of Feb 2026 |
| Pricing | Open-Source |
| Last Release | N/A |
Who Should Use Saboteur?
- Backend teams validating retries and circuit breakers need a proxy that can fail only selected routes, methods, or headers instead of poisoning an entire network path.
- SREs running resilience checks in CI/CD need deterministic fault injection that is scriptable through the control API and visible through Prometheus metrics.
- QA engineers testing unhappy paths need reproducible 503s, timeouts, truncated bodies, and header overrides without touching application code.
- Platform teams supporting multiple services need a single HTTP proxy that can sit in front of a mock upstream, a staging API, or a service under test.
Not ideal for:
- Teams that need TCP-level network chaos across arbitrary protocols; Saboteur is HTTP-aware, not a socket shaper.
- Services that require gRPC or TLS termination on the proxy port, because those are explicitly out of scope.
- Organizations that need persistent rule storage outside a config file and runtime API state.
Key Features of Saboteur
- HTTP-aware matching — Saboteur matches on
path,path_prefix,path_regex,methods,headers, andquery_params, so you can target a single endpoint instead of broad network traffic. - Priority-based rule engine — Rules are evaluated in ascending priority order, and the first match wins. That makes failure injection deterministic when multiple rules overlap.
- Seven fault modes — Saboteur supports
latency,error,abort,timeout,body_corrupt,header_inject, andthrottle, which covers most service-resilience test cases without custom code. - Control plane on port 8081 — The UI and REST API are separated from the traffic proxy on port 8080, which keeps rule management out of the request path and simplifies automation.
- Traffic log and live stream — The
/api/trafficendpoint exposes recent requests, and/api/traffic/streamprovides Server-Sent Events for live inspection during test runs. - Prometheus metrics — Saboteur exports request totals, injected fault counts, duration histograms, active rule counts, and upstream health so CI jobs can assert behavior from metrics, not screenshots.
- Config-file plus runtime API workflow — You can define rules in YAML, override them through the API, and reload file-based config with
SIGHUPwithout restarting the process.
Saboteur vs Alternatives
| Tool | Best For | Key Differentiator | Pricing |
|---|---|---|---|
| Saboteur | HTTP-aware resilience testing | Understands URLs, methods, headers, and response bodies before injecting faults | Open-Source |
| Toxiproxy | Transport-level network chaos | Operates at TCP level and is protocol-agnostic | Open-Source |
| WireMock | API mocking and stubbing | Focuses on canned responses, not live fault injection against real upstreams | Open-Source |
| Mockoon | Local mock APIs for development | Faster to stand up for fake endpoints, less suitable for live fault chaos | Freemium |
Pick Toxiproxy when you need to break sockets, add latency at the transport layer, or simulate connection resets for any protocol. Pick WireMock when your problem is API simulation rather than resilience testing against a real backend.
Pick Mockoon when the team needs disposable mock endpoints and canned responses for frontend or mobile development. Use Saboteur when you need request-aware fault injection on live HTTP traffic, and pair it with OpenTrace when you want to see how failures propagate through traces and spans.
For CI/CD wiring and environment setup, Saboteur fits cleanly beside djevops, especially when you want test pipelines to spin up fault scenarios, run assertions, and tear everything down automatically.
How Saboteur Works
Saboteur sits between the client and an upstream HTTP service as a reverse proxy. Traffic enters the proxy port on 8080, rules are evaluated against the request, and the first matching rule can mutate the request, alter the response, or short-circuit the call entirely.
The design is simple on purpose. The control plane is separate from the data plane, the configuration is YAML or environment-variable driven, and the rule matcher is explicit about precedence and match criteria. That makes Saboteur a good fit for tests that must be repeatable in CI and understandable when a failure fires.
A minimal run looks like this:
docker run -p 8080:8080 -p 8081:8081 \
-e UPSTREAM_URL=http://my-service:3000 \
yourname/saboteur
This starts the proxy on port 8080 and the control UI plus API on port 8081. Point your client at http://localhost:8080, then open http://localhost:8081 to inspect traffic and manage rules. If you add YAML config, Saboteur can reload file-based rules with SIGHUP and preserve runtime rules created over the API.
Saboteur's fault model is practical rather than theoretical. latency can delay either request forwarding or response delivery, error can synthesize an HTTP status without contacting upstream, body_corrupt can produce invalid JSON or truncated payloads, and header_inject can emulate broken intermediaries or auth changes. That gives you enough surface area to test retries, timeouts, idempotency, and client-side parsing without editing the application.
Pros and Cons of Saboteur
Pros:
- HTTP semantic awareness means failures can be scoped to endpoints, verbs, headers, or query params instead of affecting every connection.
- Fast control loop through the REST API lets automation toggle rules, update percentages, and clear traffic logs without restarting the proxy.
- Prometheus visibility makes it easy to assert injected faults and upstream health in CI or staging.
- Docker-first workflow keeps local setup trivial for ephemeral test environments.
- Atomic config reloads reduce test flakiness when file-based rules change during a run.
- Traffic inspection UI gives engineers a quick way to verify what matched and what fault was applied.
Cons:
- No TCP-layer chaos means it will not replace tools like Toxiproxy for protocol-agnostic transport testing.
- No gRPC support limits use in service meshes or RPC-heavy backends.
- No persistent rule store beyond config files and runtime state, so you need external lifecycle management for long-lived environments.
- No TLS termination on the proxy port can complicate tests that expect the proxy itself to handle HTTPS.
- Rule complexity grows quickly when many overlapping matchers and percentages are active, so teams need naming discipline.
Getting Started with Saboteur
Install Saboteur with Docker first, then point it at a real upstream and add a single fault rule through the control API.
docker run -p 8080:8080 -p 8081:8081 \
-e UPSTREAM_URL=http://localhost:3000 \
yourname/saboteur
curl -X POST http://localhost:8081/api/rules \
-H 'Content-Type: application/json' \
-d '{"id":"test-error","enabled":true,"priority":1,"percentage":100,"match":{},"fault":{"type":"error","status_code":503}}'
After the container starts, send traffic to port 8080 and the proxy will forward requests to the upstream target unless a rule intercepts them. The first rule above forces a 503 for every matching request, which is a clean way to verify retry logic, fallback rendering, and alert thresholds before you start narrowing the match criteria.
If you prefer file-based config, mount a YAML file and pass --config /etc/saboteur/config.yaml. That path is better when you want the same fault profile in local dev, staging, and CI, while still using the API for temporary runtime overrides.
Verdict
Saboteur is the strongest option for HTTP-layer resilience testing when you need request-aware faults instead of TCP noise. Its main strength is precise matching on HTTP semantics, and its main caveat is the lack of gRPC and transport-level chaos. If your goal is reproducible failure injection for web services, Saboteur is worth adopting.



