OpenFeign/feign · error · IOException

Invalid status( ) executing

Error message

Invalid status(%s) executing %s %s

What it means

Thrown as an IllegalStateException (Feign's error status decoder) when the HTTP response status code is outside the 200-299 success range configured for the client. It fires in convertResponse after the server replies with an error status (e.g., 404, 500), meaning the request reached the server but was rejected or failed server-side; the placeholders carry the numeric status, the HTTP method, and the request URL.

Solutions

  1. Check the status code and response body (via an ErrorDecoder) to distinguish client errors (4xx: fix the request URL, headers, or payload) from server errors (5xx: retry or report to the service owner)
  2. Register a custom ErrorDecoder in Feign.builder().errorDecoder(...) to map statuses to domain-specific exceptions instead of the generic message
  3. For retryable server errors, throw a RetryableException from your ErrorDecoder so Feign's Retryer can re-issue the request
  4. Verify the Target URL and path templates are correct if the status is 404/405
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at core/src/main/java/feign/DefaultClient.java:99 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10). Data as JSON: /api/errors/573ca9b794e7316f. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/feign/DefaultClient.java:99

      boolean disableRequestBuffering) {
    super();
    this.sslContextFactory = sslContextFactory;
    this.hostnameVerifier = hostnameVerifier;
    this.disableRequestBuffering = disableRequestBuffering;
  }

  @Override
  public Response execute(Request request, Options options) throws IOException {
    HttpURLConnection connection = convertAndSend(request, options);
    return convertResponse(connection, request);
  }

  Response convertResponse(HttpURLConnection connection, Request request) throws IOException {
    int status = connection.getResponseCode();
    String reason = connection.getResponseMessage();

    if (status < 0) {
      throw new IOException(
          format(
              "Invalid status(%s) executing %s %s",
              status, connection.getRequestMethod(), connection.getURL()));
    }

    Map<String, Collection<String>> headers = new TreeMap<>(CASE_INSENSITIVE_ORDER);
    for (Map.Entry<String, List<String>> field : connection.getHeaderFields().entrySet()) {
      // response message
      if (field.getKey() != null) {
        headers.put(field.getKey(), field.getValue());
      }
    }

    Integer length = connection.getContentLength();
    if (length < 0) {
      // -1 signals unknown or above Integer.MAX_VALUE; any other negative value is a malformed
      // header that HttpURLConnection surfaces verbatim
      length = null;

View on GitHub (pinned to e2a1e27560)