Skip to content
Arnel Robles edited this page Sep 29, 2026 · 1 revision

HttpClient (Carom.Http)

using Carom;
using Carom.Http;

services.AddHttpClient("github")
    .AddCaromResilience(b => b.WithTimeout(TimeSpan.FromSeconds(10)));

AddCaromResilience() with no arguments uses Bounce.Times(3). The Func<Bounce, Bounce> overload starts from Bounce.Times(3) as well. CaromHttpHandler can also be used directly as a DelegatingHandler.

What retries

Without a When predicate, a call retries on HttpRequestException (network errors) and on these status codes: 408, 429, 502, 503 and 504. Anything else, 500 included, is returned as is. With a When predicate, your predicate decides instead.

A transient status is turned into a TransientHttpException, which carries StatusCode. When retries run out you get that exception, not the last response. Retry-After is not read.

Which requests retry

Only idempotent methods retry by default: GET, HEAD, OPTIONS, PUT, DELETE and TRACE. POST and PATCH are sent once. Set RetryNonIdempotentRequests = true on the handler if your endpoint is safe to repeat.

Request bodies

A body is buffered before the first attempt so a retry sends it again. The bound is MaxRetryBufferBytes, 1 MB by default.

  • A body with a declared Content-Length above the bound is sent once, without retry.
  • A body with no declared length that turns out to be over the bound fails with HttpRequestException, because the stream is already partly read and cannot be sent whole.

Timeout

WithTimeout covers all attempts, and it cancels the request in flight. Before 2.0.1 the handler ignored WithTimeout, WithMaxDelay and When.

Clone this wiki locally