The following examples show how to add chaos/fault injection to expectations using MockServer.

Inject a 503 Service Unavailable error on 30% of matched requests, with a Retry-After header telling the client to wait 30 seconds before retrying. Useful for testing retry logic and backoff strategies.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/service")
    )
    .withChaos(
        httpChaosProfile()
            .withErrorStatus(503)
            .withErrorProbability(0.3)
            .withRetryAfter("30")
    )
    .respond(
        response()
            .withStatusCode(200)
            .withBody("{\"status\":\"ok\"}")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/api/service"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"status\":\"ok\"}"
    },
    "chaos": {
        "errorStatus": 503,
        "errorProbability": 0.3,
        "retryAfter": "30"
    }
}).then(
    function () { console.log("expectation created"); },
    function (error) { console.log(error); }
);
from mockserver import MockServerClient, HttpRequest, HttpResponse, HttpChaosProfile

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/api/service")
).with_chaos(
    HttpChaosProfile(error_status=503, error_probability=0.3, retry_after="30")
).respond(
    HttpResponse.response('{"status":"ok"}', status_code=200)
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.request(path: '/api/service')
).with_chaos(
    MockServer::HttpChaosProfile.new(error_status: 503, error_probability: 0.3, retry_after: '30')
).respond(
    MockServer::HttpResponse.response(body: '{"status":"ok"}', status_code: 200)
)
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/api/service"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"status\":\"ok\"}"
    },
    "chaos": {
        "errorStatus": 503,
        "errorProbability": 0.3,
        "retryAfter": "30"
    }
}'

See REST API for full JSON specification

Always return a 429 Too Many Requests error with a Retry-After header. Set errorProbability to 1.0 for deterministic behaviour (every request is rejected). Useful for testing how your application handles rate limiting from third-party APIs.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/external-service")
    )
    .withChaos(
        httpChaosProfile()
            .withErrorStatus(429)
            .withErrorProbability(1.0)
            .withRetryAfter("60")
    )
    .respond(
        response()
            .withStatusCode(200)
            .withBody("{\"data\":\"result\"}")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/api/external-service"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"data\":\"result\"}"
    },
    "chaos": {
        "errorStatus": 429,
        "errorProbability": 1.0,
        "retryAfter": "60"
    }
}).then(
    function () { console.log("expectation created"); },
    function (error) { console.log(error); }
);
from mockserver import MockServerClient, HttpRequest, HttpResponse, HttpChaosProfile

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/api/external-service")
).with_chaos(
    HttpChaosProfile(error_status=429, error_probability=1.0, retry_after="60")
).respond(
    HttpResponse.response('{"data":"result"}', status_code=200)
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.request(path: '/api/external-service')
).with_chaos(
    MockServer::HttpChaosProfile.new(error_status: 429, error_probability: 1.0, retry_after: '60')
).respond(
    MockServer::HttpResponse.response(body: '{"data":"result"}', status_code: 200)
)
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/api/external-service"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"data\":\"result\"}"
    },
    "chaos": {
        "errorStatus": 429,
        "errorProbability": 1.0,
        "retryAfter": "60"
    }
}'

See REST API for full JSON specification

Add artificial latency to responses without changing the status code. Useful for testing timeout handling, slow-response UX, and deadline propagation across services.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/slow-dependency")
    )
    .withChaos(
        httpChaosProfile()
            .withLatency(
                new Delay(TimeUnit.MILLISECONDS, 2000)
            )
    )
    .respond(
        response()
            .withStatusCode(200)
            .withBody("{\"result\":\"delayed\"}")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/api/slow-dependency"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"result\":\"delayed\"}"
    },
    "chaos": {
        "latency": {
            "timeUnit": "MILLISECONDS",
            "value": 2000
        }
    }
}).then(
    function () { console.log("expectation created"); },
    function (error) { console.log(error); }
);
from mockserver import MockServerClient, HttpRequest, HttpResponse, HttpChaosProfile, Delay

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/api/slow-dependency")
).with_chaos(
    HttpChaosProfile(latency=Delay(time_unit="MILLISECONDS", value=2000))
).respond(
    HttpResponse.response('{"result":"delayed"}', status_code=200)
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.request(path: '/api/slow-dependency')
).with_chaos(
    MockServer::HttpChaosProfile.new(latency: MockServer::Delay.new(time_unit: 'MILLISECONDS', value: 2000))
).respond(
    MockServer::HttpResponse.response(body: '{"result":"delayed"}', status_code: 200)
)
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/api/slow-dependency"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"result\":\"delayed\"}"
    },
    "chaos": {
        "latency": {
            "timeUnit": "MILLISECONDS",
            "value": 2000
        }
    }
}'

See REST API for full JSON specification

Combine error injection and latency injection in a single chaos profile. The seed makes the probabilistic error decision reproducible across runs — the same seed always produces the same inject/skip outcome for a given probability.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/payments")
    )
    .withChaos(
        httpChaosProfile()
            .withErrorStatus(500)
            .withErrorProbability(0.1)
            .withRetryAfter("10")
            .withLatency(
                new Delay(TimeUnit.MILLISECONDS, 500)
            )
            .withSeed(42L)
    )
    .respond(
        response()
            .withStatusCode(200)
            .withBody("{\"transactionId\":\"abc-123\"}")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/api/payments"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"transactionId\":\"abc-123\"}"
    },
    "chaos": {
        "errorStatus": 500,
        "errorProbability": 0.1,
        "retryAfter": "10",
        "latency": {
            "timeUnit": "MILLISECONDS",
            "value": 500
        },
        "seed": 42
    }
}).then(
    function () { console.log("expectation created"); },
    function (error) { console.log(error); }
);
from mockserver import MockServerClient, HttpRequest, HttpResponse, HttpChaosProfile, Delay

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/api/payments")
).with_chaos(
    HttpChaosProfile(
        error_status=500,
        error_probability=0.1,
        retry_after="10",
        latency=Delay(time_unit="MILLISECONDS", value=500),
        seed=42
    )
).respond(
    HttpResponse.response('{"transactionId":"abc-123"}', status_code=200)
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.request(path: '/api/payments')
).with_chaos(
    MockServer::HttpChaosProfile.new(
        error_status: 500,
        error_probability: 0.1,
        retry_after: '10',
        latency: MockServer::Delay.new(time_unit: 'MILLISECONDS', value: 500),
        seed: 42
    )
).respond(
    MockServer::HttpResponse.response(body: '{"transactionId":"abc-123"}', status_code: 200)
)
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/api/payments"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"transactionId\":\"abc-123\"}"
    },
    "chaos": {
        "errorStatus": 500,
        "errorProbability": 0.1,
        "retryAfter": "10",
        "latency": {
            "timeUnit": "MILLISECONDS",
            "value": 500
        },
        "seed": 42
    }
}'

See REST API for full JSON specification

Chaos profiles work on forwarded (proxied) responses too — not just mocked responses. This lets you inject faults into calls to real upstream services, making MockServer a chaos proxy for testing how your application handles unreliable dependencies.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/upstream-service")
    )
    .withChaos(
        httpChaosProfile()
            .withErrorStatus(503)
            .withErrorProbability(0.5)
            .withLatency(
                new Delay(TimeUnit.MILLISECONDS, 1000)
            )
    )
    .forward(
        forward()
            .withHost("upstream.example.com")
            .withPort(443)
            .withScheme(HttpForward.Scheme.HTTPS)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/api/upstream-service"
    },
    "httpForward": {
        "host": "upstream.example.com",
        "port": 443,
        "scheme": "HTTPS"
    },
    "chaos": {
        "errorStatus": 503,
        "errorProbability": 0.5,
        "latency": {
            "timeUnit": "MILLISECONDS",
            "value": 1000
        }
    }
}).then(
    function () { console.log("expectation created"); },
    function (error) { console.log(error); }
);
from mockserver import MockServerClient, HttpRequest, HttpChaosProfile, HttpForward, Delay

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/api/upstream-service")
).with_chaos(
    HttpChaosProfile(
        error_status=503,
        error_probability=0.5,
        latency=Delay(time_unit="MILLISECONDS", value=1000)
    )
).forward(
    HttpForward(host="upstream.example.com", port=443, scheme="HTTPS")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.request(path: '/api/upstream-service')
).with_chaos(
    MockServer::HttpChaosProfile.new(
        error_status: 503,
        error_probability: 0.5,
        latency: MockServer::Delay.new(time_unit: 'MILLISECONDS', value: 1000)
    )
).forward(
    MockServer::HttpForward.new(host: 'upstream.example.com', port: 443, scheme: 'HTTPS')
)
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/api/upstream-service"
    },
    "httpForward": {
        "host": "upstream.example.com",
        "port": 443,
        "scheme": "HTTPS"
    },
    "chaos": {
        "errorStatus": 503,
        "errorProbability": 0.5,
        "latency": {
            "timeUnit": "MILLISECONDS",
            "value": 1000
        }
    }
}'

See REST API for full JSON specification

Use failRequestCount to make the first N requests fail, then recover automatically. This is ideal for testing that your client retries and eventually succeeds. In this example the first 2 matching requests return a 503 error; from request 3 onward the normal 200 response is returned.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/service")
    )
    .withChaos(
        httpChaosProfile()
            .withErrorStatus(503)
            .withErrorProbability(1.0)
            .withFailRequestCount(2)
    )
    .respond(
        response()
            .withStatusCode(200)
            .withBody("{\"status\":\"ok\"}")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/api/service"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"status\":\"ok\"}"
    },
    "chaos": {
        "errorStatus": 503,
        "errorProbability": 1.0,
        "failRequestCount": 2
    }
}).then(
    function () { console.log("expectation created"); },
    function (error) { console.log(error); }
);
from mockserver import MockServerClient, HttpRequest, HttpResponse, HttpChaosProfile

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/api/service")
).with_chaos(
    HttpChaosProfile(error_status=503, error_probability=1.0, fail_request_count=2)
).respond(
    HttpResponse.response('{"status":"ok"}', status_code=200)
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.request(path: '/api/service')
).with_chaos(
    MockServer::HttpChaosProfile.new(error_status: 503, error_probability: 1.0, fail_request_count: 2)
).respond(
    MockServer::HttpResponse.response(body: '{"status":"ok"}', status_code: 200)
)
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/api/service"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"status\":\"ok\"}"
    },
    "chaos": {
        "errorStatus": 503,
        "errorProbability": 1.0,
        "failRequestCount": 2
    }
}'

See REST API for full JSON specification

Setting errorProbability to 1.0 makes every matched request return the error. This simulates a complete outage of the downstream service — useful for game-day exercises and verifying circuit-breaker behaviour.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/critical-service")
    )
    .withChaos(
        httpChaosProfile()
            .withErrorStatus(503)
            .withErrorProbability(1.0)
            .withRetryAfter("120")
    )
    .respond(
        response()
            .withStatusCode(200)
            .withBody("{\"healthy\":true}")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/api/critical-service"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"healthy\":true}"
    },
    "chaos": {
        "errorStatus": 503,
        "errorProbability": 1.0,
        "retryAfter": "120"
    }
}).then(
    function () { console.log("expectation created"); },
    function (error) { console.log(error); }
);
from mockserver import MockServerClient, HttpRequest, HttpResponse, HttpChaosProfile

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/api/critical-service")
).with_chaos(
    HttpChaosProfile(error_status=503, error_probability=1.0, retry_after="120")
).respond(
    HttpResponse.response('{"healthy":true}', status_code=200)
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.request(path: '/api/critical-service')
).with_chaos(
    MockServer::HttpChaosProfile.new(error_status: 503, error_probability: 1.0, retry_after: '120')
).respond(
    MockServer::HttpResponse.response(body: '{"healthy":true}', status_code: 200)
)
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/api/critical-service"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"healthy\":true}"
    },
    "chaos": {
        "errorStatus": 503,
        "errorProbability": 1.0,
        "retryAfter": "120"
    }
}'

See REST API for full JSON specification