OpenFeign/feign · error · IllegalStateException
Too many constructors marked with @FeignExceptionConstructor
Error message
Too many constructors marked with @FeignExceptionConstructor
What it means
Thrown by ExceptionGenerator.getConstructor when more than one constructor of the exception class is annotated with @FeignExceptionConstructor. The annotation designates a single preferred constructor, so multiple annotated constructors make the choice ambiguous and the library refuses to guess.
Solutions
- Keep @FeignExceptionConstructor on exactly one constructor and remove it from the others
- If both constructors are needed, make one delegate to the annotated one via this(...) chaining instead of annotating both
Example fix
// before
public class ApiError extends RuntimeException {
@FeignExceptionConstructor
public ApiError(int status, String body) { ... }
@FeignExceptionConstructor
public ApiError(String body) { this(0, body); }
}
// after
public class ApiError extends RuntimeException {
@FeignExceptionConstructor
public ApiError(int status, String body) { ... }
public ApiError(String body) { this(0, body); }
} Defensive patterns
Strategy: validation
Validate before calling
long marked = Arrays.stream(ApiError.class.getConstructors())
.filter(c -> c.isAnnotationPresent(FeignExceptionConstructor.class)).count();
if (marked > 1) throw new IllegalStateException("Only one @FeignExceptionConstructor allowed"); Try / catch
try { Feign.builder().errorDecoder(decoder).build(); }
catch (IllegalStateException e) { if (e.getMessage().contains("Too many constructors")) { ... } } Prevention
- Annotate exactly one constructor per exception class
- Use constructor chaining (this(...)) for alternate signatures instead of extra annotations
- Add an ArchUnit/reflection test asserting a single annotation per exception class
When it happens
Trigger: Annotating two or more constructors of the same exception class with @FeignExceptionConstructor, often after adding an overloaded constructor and annotating both.
Common situations: Adding a convenience constructor for tests and marking both with the annotation; merging branches where each added an annotated constructor.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot generate exception - check constructor parameter…
- Cannot find any suitable constructor in class
- Cannot access constructor
- Cannot instantiate exception with constructor
- Cannot invoke constructor
AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10).
Data as JSON: /api/errors/c6426725aa5ad422.
Report an issue: GitHub.
Appendix: source
Thrown at annotation-error-decoder/src/main/java/feign/error/ExceptionGenerator.java:223
private Constructor<? extends Exception> getConstructor(
Class<? extends Exception> exceptionClass) {
Constructor<? extends Exception> preferredConstructor = null;
for (Constructor<?> constructor : exceptionClass.getConstructors()) {
FeignExceptionConstructor exceptionConstructor =
constructor.getAnnotation(FeignExceptionConstructor.class);
if (exceptionConstructor == null) {
continue;
}
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes.length == 0) {
continue;
}
if (preferredConstructor == null) {
preferredConstructor = (Constructor<? extends Exception>) constructor;
} else {
throw new IllegalStateException(
"Too many constructors marked with @FeignExceptionConstructor");
}
}
if (preferredConstructor == null) {
try {
return exceptionClass.getConstructor();
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
"Cannot find any suitable constructor in class ["
+ exceptionClass.getName()
+ "] - did you forget to mark one with @FeignExceptionConstructor or at least"
+ " have a public default constructor?",
e);
}
}
return preferredConstructor;
}View on GitHub (pinned to e2a1e27560)