quarkusio/quarkus · error · IllegalArgumentException
parameterized type %s can not be inherited from by %s (or a
Error message
parameterized type %s can not be inherited from by %s (or a predecessor) with different type arguments.
What it means
During REST client build-time generation, Quarkus walks the interface hierarchy of a client interface to resolve generic type arguments. If the same parameterized interface appears twice in the hierarchy with different type arguments — which plain Java should prevent — the mapping cache detects a conflict and aborts. This usually indicates duplicate/conflicting versions of a library on the classpath or bytecode manipulated in ways Java's compiler would not produce.
Source
Thrown at extensions/resteasy-reactive/rest-client-jaxrs/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java:1565
private void fillHierarchyIdentifierTypeLookupMap(IndexView index, ClassInfo owner,
Map<DotName, Map<String, Type>> hierarchyIdentifierTypeLookupMap) {
List<Type> interfaceTypes = owner.interfaceTypes();
// no need to check for Object, not an interface
if (!owner.isInterface() || interfaceTypes.isEmpty()) {
return;
}
for (Type interfaceType : interfaceTypes) {
Type resolvedInterfaceType = resolveType(interfaceType,
hierarchyIdentifierTypeLookupMap.getOrDefault(owner.name(), Collections.emptyMap()), null);
Map<String, Type> identifierTypeLookupMap = determineIdentifierTypeLookupMap(index, resolvedInterfaceType);
if (hierarchyIdentifierTypeLookupMap.putIfAbsent(interfaceType.name(), identifierTypeLookupMap) != null) {
if (!hierarchyIdentifierTypeLookupMap.get(interfaceType.name()).equals(identifierTypeLookupMap)) {
// Just to be safe, java should prevent this. This could maybe happen with different versions of a library on the classpath?
throw new IllegalArgumentException(
"parameterized type %s can not be inherited from by %s (or a predecessor) with different type arguments."
.formatted(interfaceType.name(), owner.name()));
}
}
fillHierarchyIdentifierTypeLookupMap(index, index.getClassByName(interfaceType.name()),
hierarchyIdentifierTypeLookupMap);
}
}
private Map<String, Type> determineIdentifierTypeLookupMap(IndexView index, Type type) {
Map<String, Type> result = new HashMap<>();
if (type.kind() == PARAMETERIZED_TYPE) {
ClassInfo classInfo = index.getClassByName(type.name());
ParameterizedType parameterizedType = type.asParameterizedType();
for (int i = 0; i < parameterizedType.arguments().size(); i++) {
// No need to check if the class even has type parameters, if the type has an argument for it, then the class must have a type parameter for itView on GitHub (pinned to e1c734241f)
Solutions
- Run mvn dependency:tree and resolve duplicate/conflicting versions of the library owning the interface with dependencyManagement or exclusions
- Clean and rebuild (mvn clean install) to remove stale generated/indexed classes
- Ensure the generic interface hierarchy is consistent in source — a single type argument per interface across all subtypes
- If caused by a generated sub-resource, regenerate/refresh annotation-indexed sources
Example fix
// before (pom.xml mixed versions)
<dependency><groupId>com.example</groupId><artifactId>api-lib</artifactId><version>1.0</version></dependency>
<dependency><groupId>com.example</groupId><artifactId>api-lib</artifactId><version>2.0</version></dependency>
// after
<dependencyManagement>
<dependencies>
<dependency><groupId>com.example</groupId><artifactId>api-lib</artifactId><version>2.0</version></dependency>
</dependencies>
</dependencyManagement> Defensive patterns
Strategy: validation
Validate before calling
// Before building, check dependency conflicts:
// mvn dependency:tree -Dincludes=com.example:api-lib
// Ensure only one version of the library defining the generic interface exists.
Set<String> versions = new LinkedHashSet<>();
ClassLoader cl = Thread.currentThread().getContextClassLoader();
// verify a single consistent jar provides the interface:
String res = "com/example/Repo.class";
try (InputStream in = cl.getResourceAsStream(res)) {
if (in == null) throw new IllegalStateException("interface missing from classpath");
} Prevention
- Keep library versions aligned via dependencyManagement/BOM
- Run mvn dependency:tree in CI to detect version convergence issues
- Avoid shaded jars that redefine the same class names
- Rebuild cleanly after dependency upgrades
When it happens
Trigger: A client interface (or its superinterfaces) inherits the same generic interface through two paths with different type parameters, e.g. via different library versions providing classes like Foo extends Repo<String> and Repo<Integer> for the same interface name.
Common situations: Mixed versions of a library on the classpath after a dependency upgrade; shaded/relocated jars redefining the same DotName; build-time vs runtime classpath mismatch in fast-jar; generated sub-resource interfaces conflicting with hand-written ones.
Related errors
- multipart responses can only be mapped to non-generic classe
- Type variable %s of %s could not be resolved.
- Map parameter types must have String keys. Offending method
- Raw Map parameter types are not supported. Offending method
- Raw MultivaluedMap parameter types are not supported. Offend
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e6b864fee4948881.
Report an issue: GitHub.