{"record":{"id":"85ac56fb64861d6e","repo":"OpenFeign/feign","slug":"not-an-iterator-type-rawtype-85ac56","errorCode":null,"errorMessage":"Not an iterator type ${rawType}","messagePattern":"Not an iterator type (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"jackson3/src/main/java/feign/jackson3/Jackson3IteratorDecoder.java","lineNumber":104,"sourceCode":"      }\n      reader.reset();\n      return new Jackson3Iterator<Object>(\n          actualIteratorTypeArgument(type), mapper, response, reader);\n    } catch (JacksonException e) {\n      if (e.getCause() != null && e.getCause() instanceof IOException) {\n        throw IOException.class.cast(e.getCause());\n      }\n      throw e;\n    }\n  }\n\n  private static Type actualIteratorTypeArgument(Type type) {\n    if (!(type instanceof ParameterizedType)) {\n      throw new IllegalArgumentException(\"Not supported type \" + type.toString());\n    }\n    ParameterizedType parameterizedType = (ParameterizedType) type;\n    if (!Iterator.class.equals(parameterizedType.getRawType())) {\n      throw new IllegalArgumentException(\n          \"Not an iterator type \" + parameterizedType.getRawType().toString());\n    }\n    return ((ParameterizedType) type).getActualTypeArguments()[0];\n  }\n\n  public static Jackson3IteratorDecoder create() {\n    return create(Collections.<JacksonModule>emptyList());\n  }\n\n  public static Jackson3IteratorDecoder create(Iterable<JacksonModule> modules) {\n    return new Jackson3IteratorDecoder(\n        JsonMapper.builder()\n            .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)\n            // Disable FAIL_ON_TRAILING_TOKENS for iterator: we read a JSON array element by\n            // element, so there are always \"trailing tokens\" (the remaining array elements)\n            .disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)\n            .addModules(modules)\n            .build());","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/OpenFeign/feign/blob/e2a1e27560a1e68840c34f031afca88b36096e30/jackson3/src/main/java/feign/jackson3/Jackson3IteratorDecoder.java#L86-L122","documentation":"Jackson3IteratorDecoder requires the raw type of the declared return type to be exactly java.util.Iterator. Any other parameterized type (List<T>, Page<T>, etc.) throws IllegalArgumentException('Not an iterator type ...').","triggerScenarios":"Declaring a Feign method returning List<ItemDto>, Set<ItemDto>, or any other generic type and decoding with Jackson3IteratorDecoder; the guard Iterator.class.equals(parameterizedType.getRawType()) fails at decode time.","commonSituations":"Registering the iterator decoder as the global decoder while most endpoints return List<T>; switching a method's return type from Iterator<T> to List<T> without changing the decoder configuration.","solutions":["Change the return type to Iterator<ItemDto> if streaming is desired","Keep List<ItemDto> and use Jackson3Decoder instead of the iterator decoder","Register Jackson3IteratorDecoder only for specific methods/targets that genuinely stream Iterator<T>","If wrapping in a custom container, implement a dedicated Decoder rather than reusing this one"],"exampleFix":"// before\n@Get(\"/items\") List<ItemDto> getItems(); // with Jackson3IteratorDecoder\n// after\n@Get(\"/items\") Iterator<ItemDto> getItems(); // with Jackson3IteratorDecoder","handlingStrategy":"type-guard","validationCode":"Type t = method.getGenericReturnType();\nif (t instanceof ParameterizedType\n    && ((ParameterizedType) t).getRawType() != java.util.Iterator.class) {\n  throw new IllegalStateException(\"Jackson3IteratorDecoder needs Iterator<T>, got: \" + t);\n}","typeGuard":"static boolean isExactlyIterator(Type t) {\n  return t instanceof ParameterizedType\n      && java.util.Iterator.class.equals(((ParameterizedType) t).getRawType());\n}","tryCatchPattern":"try {\n  return decoder.decode(response, type);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Not an iterator type\")) {\n    return fallbackListDecoder.decode(response, type);\n  }\n  throw e;\n}","preventionTips":["Keep Iterator<T> and List<T> endpoints on separate decoders - do not register the iterator decoder globally","Document per-interface which decoder is expected","Add startup-time validation of return types when configuring the Feign builder","Prefer Iterator<ItemDto> for large/streaming responses; List<ItemDto> otherwise"],"tags":["jackson","generics","feign","decoder","illegal-argument"],"backgroundTag":"invalid-argument-value","analyzedSha":"e2a1e27560a1e68840c34f031afca88b36096e30","analyzedAt":"2026-09-10T12:37:37.238Z","contentChangedAt":"2026-09-10T12:37:37.238Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}