quarkusio/quarkus · error · MessageBundleException

Duplicate key [%s] found on %s

Error message

Duplicate key [%s] found on %s

What it means

Within one message bundle interface, each resolved message key must be unique. getKey() derives the key from the method name or @Message#key; if two methods resolve to the same key, template lookup would be ambiguous, so the build fails with the duplicate key and the bundle interface.

Source

Thrown at extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/MessageBundleProcessor.java:1070

                        messageAnnotation = defaultBundleMethod.annotation(Names.MESSAGE);
                    } else {
                        messageAnnotation = method.annotation(Names.MESSAGE);
                    }

                    if (messageAnnotation == null) {
                        LOG.debugf("@Message not declared on %s#%s - using the default key/value", bundleInterface, method);
                        messageAnnotation = AnnotationInstance.builder(Names.MESSAGE).value(Message.DEFAULT_VALUE)
                                .add("name", Message.DEFAULT_NAME).build();
                    }

                    String key = getKey(method, messageAnnotation, defaultKeyValue);
                    if (key.equals(MESSAGE)) {
                        throw new MessageBundleException(String.format(
                                "A message bundle interface method must not use the key 'message' which is reserved for dynamic lookup; defined for %s#%s()",
                                bundleInterface, method.name()));
                    }
                    if (keyMap.containsKey(key)) {
                        throw new MessageBundleException(String.format("Duplicate key [%s] found on %s", key, bundleInterface));
                    }
                    keyMap.put(key, new SimpleMessageMethod(method));

                    boolean generatedTemplate = false;
                    String messageTemplate = messageTemplates.get(method.name());
                    if (messageTemplate == null) {
                        messageTemplate = getMessageAnnotationValue(messageAnnotation, true);
                    }

                    if (messageTemplate == null && defaultBundleInterface != null) {
                        // method is annotated with @Message without value() -> fallback to default locale
                        messageTemplate = getMessageAnnotationValue((defaultBundleInterface.method(method.name(),
                                method.parameterTypes().toArray(new Type[] {}))).annotation(Names.MESSAGE), true);
                    }

                    // We need some special handling for enum message bundle methods
                    // A message bundle method that accepts an enum and has no message template receives a generated template:
                    // {#when enumParamName}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Rename one of the methods or set a distinct @Message(key = "...") so each key is unique.
  2. Remove the redundant duplicate method if it serves the same message.
  3. Search the bundle interface for repeated method names and @Message key values before rebuilding.

Example fix

// before
String hello();
@Message(key = "hello")
String hi();

// after
String hello();
@Message(key = "hi")
String hi();
Defensive patterns

Strategy: validation

Validate before calling

// Detect duplicate keys in a bundle interface
java.util.Map<String,Integer> seen = new java.util.HashMap<>();
for (java.lang.reflect.Method m : AppMessages.class.getDeclaredMethods()) {
    Message msg = m.getAnnotation(Message.class);
    String key = (msg != null && !Message.DEFAULT_NAME.equals(msg.key())) ? msg.key() : m.getName();
    if (seen.put(key, 1) != null) throw new IllegalStateException("Duplicate key: " + key);
}

Prevention

When it happens

Trigger: Two methods mapping to the same key, e.g. `String hello();` and `@Message(key="hello") String hi();`, or overloads whose keys collapse (same name, same key derivation).

Common situations: Copy-pasting a method and forgetting to rename it or its @Message key; adding an overload of an existing bundle method (keys don't consider parameters); merging branches that both added a method with the same key.

Related errors


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