OpenFeign/feign · error · DecodeException

${e.getMessage()}

Error message

${e.getMessage()}

What it means

While advancing the iterator, JacksonIteratorDecoder reads the next value with the Jackson ObjectMapper; any IOException during parsing is rethrown as DecodeException carrying the parser's message and the response status. This surfaces malformed JSON or truncated streams mid-iteration rather than at call time.

Solutions

  1. Catch DecodeException around iteration and inspect the cause for the exact parse error and location.
  2. Verify the endpoint actually returns well-formed JSON array content for the whole body.
  3. Check for proxies/gateways truncating responses; enable retries at the client level for transient cuts.
  4. Confirm content-type and that Jackson's ObjectReader config matches the payload structure.

Example fix

// before
try (Iterator<User> it = users.iterator()) {
  while (it.hasNext()) { process(it.next()); } // DecodeException mid-stream
}
// after
try (Iterator<User> it = users.iterator()) {
  while (it.hasNext()) {
    try { process(it.next()); }
    catch (DecodeException e) { log.error("JSON stream failed: {}", e.getMessage(), e.getCause()); break; }
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before iterating
if (response.status() != 200) throw new IllegalStateException("Non-200: " + response.status());
// and confirm Content-Type is JSON
if (!String.valueOf(response.headers().get("content-type")).contains("json")) {
  throw new IllegalStateException("Response is not JSON");
}

Try / catch

try (Iterator<User> it = users) {
  while (it.hasNext()) { process(it.next()); }
} catch (feign.codec.DecodeException e) {
  logger.error("Stream decode failed at status {}: {}", e.status(), e.getMessage(), e.getCause());
  // fall back to a full re-fetch with JacksonDecoder if idempotent
}

Prevention

When it happens

Trigger: Iterating a JSON array response where the body is malformed, truncated (connection reset mid-body), not actually a JSON array, or the server returned an error document where elements were expected; readValue fails inside readNext during hasNext()/next().

Common situations: Upstream gateway returning HTML error pages with 200; proxies closing connections early; response content-type JSON but body invalid; server-side serialization bug on later array elements.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at jackson/src/main/java/feign/jackson/JacksonIteratorDecoder.java:163

      try {
        JsonToken jsonToken = parser.nextToken();
        if (jsonToken == null) {
          return null;
        }

        if (jsonToken == JsonToken.START_ARRAY) {
          jsonToken = parser.nextToken();
        }

        if (jsonToken == JsonToken.END_ARRAY) {
          ensureClosed(this);
          return null;
        }

        return objectReader.readValue(parser);
      } catch (IOException e) {
        // Input Stream closed automatically by parser
        throw new DecodeException(response.status(), e.getMessage(), response.request(), e);
      }
    }

    @Override
    public T next() {
      if (current != null) {
        T tmp = current;
        current = null;
        return tmp;
      }
      T next = readNext();
      if (next == null) {
        throw new NoSuchElementException();
      }
      return next;
    }

    @Override

View on GitHub (pinned to e2a1e27560)