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
- Catch DecodeException around iteration and inspect the cause for the exact parse error and location.
- Verify the endpoint actually returns well-formed JSON array content for the whole body.
- Check for proxies/gateways truncating responses; enable retries at the client level for transient cuts.
- 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
- Validate status and content-type before streaming
- Only stream from idempotent, trusted endpoints
- Watch for gateways/proxies that truncate bodies
- Set sane read timeouts so partial bodies fail fast
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
- ${e.getMessage()}
- is not a type supported by this encoder.
- StreamDecoder supports types other than stream. When type…
- Not supported type
- Not an iterator type
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;
}
@OverrideView on GitHub (pinned to e2a1e27560)