GET /flaky
Returns a failure response with probability p, otherwise 200. Both outcomes include X-Chaos-Flaky-Failed and X-Chaos-Flaky-Probability headers so clients can distinguish a chaos failure from a real one.
p
Failure probability. Range: 0.0–1.0. Default: 0.5.
status
HTTP status code returned on failure. Range: 100–599. Default: 500.
build a request:
expect: Either 200 OK or the chosen failure status, decided by probability. Both responses carry X-Chaos-Flaky-Failed (true/false) and X-Chaos-Flaky-Probability.
# Single call — succeeds or fails based on probability
curl -i 'https://chaos.catastrophic.io/flaky?p=0.5&status=500'
# Retry loop, stop on first success
for attempt in 1 2 3 4 5; do
code=$(curl -s -o /dev/null -w '%{http_code}' 'https://chaos.catastrophic.io/flaky?p=0.5&status=500')
if [ "$code" = "200" ]; then
echo "Succeeded on attempt $attempt"
break
fi
echo "Attempt $attempt failed with $code"
done
# Retry up to 5 times, stop on first success.
import urllib.request, urllib.error
url = "https://chaos.catastrophic.io/flaky?p=0.5&status=500"
for attempt in range(1, 6):
try:
urllib.request.urlopen(url)
print(f"Succeeded on attempt {attempt}")
break
except urllib.error.HTTPError as e:
print(f"Attempt {attempt} failed with {e.code}")
const url = "https://chaos.catastrophic.io/flaky?p=0.5&status=500";
for (let attempt = 1; attempt <= 5; attempt++) {
const res = await fetch(url);
if (res.ok) {
console.log(`Succeeded on attempt ${attempt}`);
break;
}
console.log(`Attempt ${attempt} failed with ${res.status}`);
}
package main
import (
"fmt"
"net/http"
)
func main() {
url := "https://chaos.catastrophic.io/flaky?p=0.5&status=500"
for attempt := 1; attempt <= 5; attempt++ {
resp, _ := http.Get(url)
resp.Body.Close()
if resp.StatusCode == 200 {
fmt.Printf("Succeeded on attempt %d\n", attempt)
break
}
fmt.Printf("Attempt %d failed with %d\n", attempt, resp.StatusCode)
}
}
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking"] }
fn main() -> Result<(), Box> {
let url = "https://chaos.catastrophic.io/flaky?p=0.5&status=500";
let client = reqwest::blocking::Client::new();
for attempt in 1..=5 {
let resp = client.get(url).send()?;
if resp.status().is_success() {
println!("Succeeded on attempt {attempt}");
break;
}
println!("Attempt {attempt} failed with {}", resp.status());
}
Ok(())
}
// Java 11+ HttpClient
import java.net.URI;
import java.net.http.*;
public class Flaky {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var req = HttpRequest.newBuilder(URI.create("https://chaos.catastrophic.io/flaky?p=0.5&status=500")).build();
for (int attempt = 1; attempt <= 5; attempt++) {
var resp = client.send(req, HttpResponse.BodyHandlers.discarding());
if (resp.statusCode() == 200) {
System.out.println("Succeeded on attempt " + attempt);
break;
}
System.out.println("Attempt " + attempt + " failed with " + resp.statusCode());
}
}
}
// .NET 6+
using var client = new HttpClient();
var url = "https://chaos.catastrophic.io/flaky?p=0.5&status=500";
for (int attempt = 1; attempt <= 5; attempt++) {
var resp = await client.GetAsync(url);
if (resp.IsSuccessStatusCode) {
Console.WriteLine($"Succeeded on attempt {attempt}");
break;
}
Console.WriteLine($"Attempt {attempt} failed with {(int)resp.StatusCode}");
}
require "net/http"
uri = URI("https://chaos.catastrophic.io/flaky?p=0.5&status=500")
1.upto(5) do |attempt|
res = Net::HTTP.get_response(uri)
if res.code == "200"
puts "Succeeded on attempt #{attempt}"
break
end
puts "Attempt #{attempt} failed with #{res.code}"
end
# Retry up to 5 times, stopping on first success.
$attempts = 0
do {
$attempts++
try {
$r = Invoke-WebRequest -Uri 'https://chaos.catastrophic.io/flaky?p=0.5&status=500'
Write-Host "Succeeded on attempt $attempts"
break
} catch {
$code = $_.Exception.Response.StatusCode.value__
Write-Host "Attempt $attempts failed with $code"
}
} while ($attempts -lt 5)
headers
body