quarkusio/quarkus · error · RestClientDefinitionException

Duplicate ClientHeaderParam annotation for header: ${headerN

Error message

Duplicate ClientHeaderParam annotation for header: ${headerName} on ${target}

What it means

Two @ClientHeaderParam annotations for the same header name were found on the client interface (e.g. at both the class and method level, or in repeated containers). Since only one value can be sent per header, the enricher throws during putAllHeaderAnnotations instead of silently choosing one.

Source

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

     * @param javaMethodField method reference in a static class field
     * @param methodCreator method for which we put the java.lang.reflect.Method to context (aka this method)
     * @param invocationBuilder Invocation.Builder in this method
     */
    private void addJavaMethodToContext(FieldDescriptor javaMethodField, MethodCreator methodCreator,
            AssignableResultHandle invocationBuilder) {
        ResultHandle javaMethod = methodCreator.readStaticField(javaMethodField);
        ResultHandle javaMethodAsObject = methodCreator.checkCast(javaMethod, Object.class);
        methodCreator.assign(invocationBuilder,
                methodCreator.invokeInterfaceMethod(INVOCATION_BUILDER_PROPERTY_METHOD, invocationBuilder,
                        methodCreator.load(INVOKED_METHOD_PROP), javaMethodAsObject));
    }

    private void putAllHeaderAnnotations(Map<String, ParamData> headerMap, ClassInfo interfaceClass,
            AnnotationInstance[] annotations) {
        for (AnnotationInstance annotation : annotations) {
            String headerName = annotation.value("name").asString();
            if (headerMap.put(headerName, new ParamData(annotation, interfaceClass)) != null) {
                throw new RestClientDefinitionException("Duplicate ClientHeaderParam annotation for header: " + headerName +
                        " on " + annotation.target());
            }
        }
    }

    // fillHeaders takes `MultivaluedMap<String, String>` as param and modifies it
    private void addHeaderParam(MethodInfo declaringMethod, MethodCreator fillHeadersCreator,
            ParamData paramData,
            BuildProducer<GeneratedClassBuildItem> generatedClasses,
            String fillerClassName,
            IndexView index) {

        AnnotationInstance annotation = paramData.annotation;
        ClassInfo declaringClass = paramData.definingClass;

        String headerName = annotation.value("name").asString();

        String[] values = annotation.value().asStringArray();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove the duplicate @ClientHeaderParam for that header name
  2. Keep a single definition at the class level if it applies everywhere
  3. Rename the header if two distinct headers were intended

Example fix

// before
@ClientHeaderParam(name = "Auth", value = "a")
interface Client { @ClientHeaderParam(name = "Auth", value = "b") String get(); }
// after
@ClientHeaderParam(name = "Auth", value = "a")
interface Client { String get(); }
Defensive patterns

Strategy: validation

Validate before calling

// Collect header names at startup to detect duplicates
Map<String,Integer> seen = new HashMap<>();
for (ClientHeaderParam a : iface.getAnnotationsByType(ClientHeaderParam.class))
    seen.merge(a.name(), 1, Integer::sum);
List<String> dupes = seen.entrySet().stream().filter(e -> e.getValue() > 1).map(Map.Entry::getKey).toList();
if (!dupes.isEmpty()) throw new IllegalStateException("Duplicate headers: " + dupes);

Prevention

When it happens

Trigger: Applying @ClientHeaderParam(name="Authorization") on both the interface and a method, or repeating the annotation for the same name; the map put returns a previous entry and the build fails.

Common situations: Copy-pasting method-level annotations after a class-level one already defines the header; inheritance from a base interface re-declaring the same header.

Related errors


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