quarkusio/quarkus · error · RestClientDefinitionException

Ambiguous %s definition, more than one method of name %s fou

Error message

Ambiguous %s definition, more than one method of name %s found on %s. Problematic interface: %s

What it means

@ClientHeaderParam (and similar Client*Param annotations) can reference a method by name, e.g. value="{computeHeader}". findMethod scans the declaring class for methods with that name; if two or more overloads exist, Quarkus cannot decide which one to call and fails the build with RestClientDefinitionException.

Source

Thrown at extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/MicroProfileRestClientEnricher.java:1073

            return valueType;
        }

        Supplier<ResultHandle> getResultHandleSupplier() {
            return resultHandleSupplier;
        }

        HeaderFillerInfo mapResultHandle(Function<Supplier<ResultHandle>, Supplier<ResultHandle>> mapper) {
            return new HeaderFillerInfo(this.valueType, this.source, mapper.apply(this.resultHandleSupplier));
        }
    }

    private MethodInfo findMethod(ClassInfo declaringClass, ClassInfo restInterface, String methodName,
            String sourceAnnotationName) {
        MethodInfo result = null;
        for (MethodInfo method : declaringClass.methods()) {
            if (method.name().equals(methodName)) {
                if (result != null) {
                    throw new RestClientDefinitionException(String.format(
                            "Ambiguous %s definition, more than one method of name %s found on %s. Problematic interface: %s",
                            sourceAnnotationName, methodName, declaringClass, restInterface));
                } else {
                    result = method;
                }
            }
        }
        return result;
    }

    private static boolean isString(Type type) {
        return type.kind() == Type.Kind.CLASS && type.name().toString().equals(String.class.getName());
    }

    private static boolean isStringArray(Type returnType) {
        return returnType.kind() == Type.Kind.ARRAY && returnType.asArrayType().constituent().name().equals(STRING);
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Rename one of the overloads so the referenced name is unique
  2. Remove the unused overload
  3. Keep exactly one method with the referenced name that returns String or String[]

Example fix

// before
String computeHeader() { ... }
String computeHeader(String name) { ... }

// after
String computeHeader() { ... }
String computeHeaderForName(String name) { ... }
Defensive patterns

Strategy: validation

Validate before calling

long count = Arrays.stream(MyClient.class.getDeclaredMethods())
    .filter(m -> m.getName().equals("computeHeader"))
    .count();
if (count > 1) {
    throw new IllegalStateException("Method referenced by ClientHeaderParam must not be overloaded");
}

Prevention

When it happens

Trigger: ClientHeaderParam value references a method name that is overloaded in the interface or referenced class, e.g. computeHeader() and computeHeader(String) both present.

Common situations: Overloading header-provider methods with and without a header-name parameter, or inheriting overloads from multiple implemented interfaces.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/443080cd77e46371. Report an issue: GitHub.