OpenFeign/feign · error · IllegalArgumentException
Not an iterator type
Error message
Not an iterator type ${rawType} What it means
Companion check in actualIteratorTypeArgument: the type is parameterized but its raw type is not java.util.Iterator, so the decoder cannot stream it and throws IllegalArgumentException 'Not an iterator type X'.
Solutions
- Return Iterator<T> from methods handled by JacksonIteratorDecoder.
- Register a composed decoder: new JacksonDecoder() for normal types and JacksonIteratorDecoder for Iterator<T> methods (or use the auto-detecting setup).
- Only set JacksonIteratorDecoder per-method/per-client where streaming is intended.
- Check the declared return type's generic raw type.
Example fix
// before .decoder(new JacksonIteratorDecoder()) // used with List<User> return types // after .decoder(new Decoder.Default(new JacksonDecoder(), new JacksonIteratorDecoder())); // and declare streaming methods as Iterator<User>
Defensive patterns
Strategy: type-guard
Validate before calling
static boolean isIteratorType(Type type) {
return type instanceof ParameterizedType
&& java.util.Iterator.class.equals(((ParameterizedType) type).getRawType());
} Type guard
static boolean suitableForIteratorDecoder(java.lang.reflect.Method m) {
Type t = m.getGenericReturnType();
return t instanceof ParameterizedType && java.util.Iterator.class.equals(((ParameterizedType) t).getRawType());
} Try / catch
try {
return feignClient.call();
} catch (feign.codec.DecodeException e) {
if (e.getCause() instanceof IllegalArgumentException && e.getCause().getMessage().startsWith("Not an iterator type")) {
throw new IllegalStateException("Use the standard JacksonDecoder for non-Iterator return types", e);
}
throw e;
} Prevention
- Use a composed Decoder that routes List<T> to JacksonDecoder and Iterator<T> to JacksonIteratorDecoder
- Do not set JacksonIteratorDecoder as the only decoder for multi-shaped APIs
- Grep Feign interfaces for return types before enabling streaming decoding
When it happens
Trigger: Using JacksonIteratorDecoder with a method returning List<User>, Collection<User>, or any other ParameterizedType that is not Iterator<T>.
Common situations: Applying the iterator decoder globally to all methods (e.g. in Feign.builder().decoder(JacksonIteratorDecoder.create())) while most methods return List<T>; migrating methods without switching back to the standard decoder.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Not supported type
- Not supported type
- Not an iterator type
- ${e.getMessage()}
- JAXB only supports decoding raw types. Found
AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10).
Data as JSON: /api/errors/3bc8c8035d7e0363.
Report an issue: GitHub.
Appendix: source
Thrown at jackson/src/main/java/feign/jackson/JacksonIteratorDecoder.java:101
}
reader.reset();
return new JacksonIterator<Object>(
actualIteratorTypeArgument(type), mapper, response, reader);
} catch (RuntimeJsonMappingException e) {
if (e.getCause() != null && e.getCause() instanceof IOException) {
throw IOException.class.cast(e.getCause());
}
throw e;
}
}
private static Type actualIteratorTypeArgument(Type type) {
if (!(type instanceof ParameterizedType)) {
throw new IllegalArgumentException("Not supported type " + type.toString());
}
ParameterizedType parameterizedType = (ParameterizedType) type;
if (!Iterator.class.equals(parameterizedType.getRawType())) {
throw new IllegalArgumentException(
"Not an iterator type " + parameterizedType.getRawType().toString());
}
return ((ParameterizedType) type).getActualTypeArguments()[0];
}
public static JacksonIteratorDecoder create() {
return create(Collections.<Module>emptyList());
}
public static JacksonIteratorDecoder create(Iterable<Module> modules) {
return new JacksonIteratorDecoder(
new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModules(modules));
}
public static JacksonIteratorDecoder create(ObjectMapper objectMapper) {
return new JacksonIteratorDecoder(objectMapper);View on GitHub (pinned to e2a1e27560)