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
- Rename one of the methods or set a distinct @Message(key = "...") so each key is unique.
- Remove the redundant duplicate method if it serves the same message.
- 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
- Never overload bundle methods (keys ignore parameters)
- Use unique @Message(key) values when method names could collide
- Review bundle interfaces for duplicates before merging branches
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
- Message bundle name [%s] declared on %s must be a valid name
- Message bundle interface name conflict - [%s] is used for bo
- Locale of [%s] conflicts with the locale [%s] of the default
- Cannot register [%s] - a localized message bundle interface
- @MessageBundle must be declared on an interface: {bundleClas
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/6728837e5c91ad4b.
Report an issue: GitHub.