Usage of EnsureSuccessStatusCode and handling of HttpRequestException it throws
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
EnsureSuccessStatusCode() is a method on HttpResponseMessage in .NET that throws an HttpRequestException if the HTTP response status code is not in the 2xx range. It provides a quick way to fail fast when an API call returns an error. The alternative is to manually check response.IsSuccessStatusCode and handle failure yourself. Understanding when to use each approach — and how to extract useful information from the exception — is essential for robust HTTP client code.
Basic Usage
EnsureSuccessStatusCode() checks response.StatusCode. If it is outside the 200-299 range, it throws HttpRequestException and disposes the response content to free resources.
Catching HttpRequestException
In .NET 5 and later, HttpRequestException has a StatusCode property. In earlier versions, you must parse the status code from the exception message or use the alternative approach below.
Alternative: Manual Status Check
Manual checking with IsSuccessStatusCode lets you read the response body before handling the error. EnsureSuccessStatusCode() disposes the content, so you cannot read error details after it throws.
Reading Error Body Before Throwing
This custom helper reads the error body before throwing, giving you the full API error message in the exception. The built-in EnsureSuccessStatusCode() does not include the response body.
Typed Error Handling
For APIs that return structured error responses (JSON with error codes and messages), create a custom exception type that deserializes the error body. This gives callers typed access to error details.
Using Polly for Retry with EnsureSuccessStatusCode
Polly integrates with HttpClient to retry transient failures (5xx, timeouts, rate limits) before you call EnsureSuccessStatusCode(). This handles intermittent failures without custom retry logic.
HttpClient with IHttpClientFactory
IHttpClientFactory manages HttpClient lifetimes and avoids socket exhaustion. Combine it with EnsureSuccessStatusCode() for clean, production-ready HTTP calls.
Common Pitfalls
- Cannot read response body after EnsureSuccessStatusCode throws: The method disposes the response content before throwing. If you need error details from the API, check
IsSuccessStatusCodemanually and read the body first. - No StatusCode property in .NET Framework / .NET Core < 5: Before .NET 5,
HttpRequestExceptiondoes not exposeStatusCode. You must parse it fromex.Messageor use the manual check pattern. - Catching Exception instead of HttpRequestException: Catching the broad
Exceptiontype hides what went wrong. Always catchHttpRequestExceptionspecifically so you can distinguish HTTP errors from network failures, timeouts, and other exception types. - Not handling timeout separately:
HttpClientthrowsTaskCanceledException(notHttpRequestException) when a request times out. Handle both exception types to cover all failure modes. - Using EnsureSuccessStatusCode for expected 404s: If your API returns 404 for "not found" as a normal business response, throwing an exception is heavy-handed. Check
response.StatusCode == HttpStatusCode.NotFoundexplicitly and returnnullor a default instead.
Summary
EnsureSuccessStatusCode()throwsHttpRequestExceptionfor non-2xx status codes- Use it for quick fail-fast behavior when any error is unexpected
- Use
IsSuccessStatusCodemanually when you need to read the error response body - In .NET 5+,
HttpRequestException.StatusCodegives direct access to the HTTP status code - Create custom exception types for APIs that return structured error responses
- Combine with Polly for retry policies on transient HTTP failures

