quarkusio/quarkus · error · MessageBundleException

Message bundle interface name conflict - [%s] is used for bo

Error message

Message bundle interface name conflict - [%s] is used for both [%s] and [%s]

What it means

MessageBundleException thrown at build time when two different interfaces annotated with @MessageBundle resolve to the same bundle name. Each bundle name is a unique template namespace, so duplicates would make bean registration and message resolution ambiguous. The build fails naming both conflicting interfaces.

Source

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

                                    names.add(enclosingClass.simpleName());
                                    enclosingName = enclosingClass.nestingType() == NestingType.TOP_LEVEL ? null
                                            : enclosingClass.enclosingClass();
                                }
                            }
                            Collections.reverse(names);
                            name = String.join("_", names);
                        }
                        LOG.debugf("Message bundle %s: name defaulted to %s", bundleClass, name);
                    }
                    if (!Namespaces.isValidNamespace(name)) {
                        throw new MessageBundleException(
                                String.format(
                                        "Message bundle name [%s] declared on %s must be a valid namespace - the value can only consist of alphanumeric characters and underscores",
                                        name, bundleClass));
                    }

                    if (found.containsKey(name)) {
                        throw new MessageBundleException(
                                String.format("Message bundle interface name conflict - [%s] is used for both [%s] and [%s]",
                                        name, bundleClass, found.get(name)));
                    }
                    found.put(name, bundleClass);

                    // Find localizations for each interface
                    String defaultLocale = getDefaultLocale(bundleAnnotation, locales);
                    List<ClassInfo> localized = new ArrayList<>();
                    for (ClassInfo implementor : index.getKnownDirectSubinterfaces(bundleClass.name())) {
                        localized.add(implementor);
                    }
                    Map<String, ClassInfo> localeToInterface = new HashMap<>();
                    for (ClassInfo localizedInterface : localized) {
                        String locale = localizedInterface.declaredAnnotation(Names.LOCALIZED).value().asString();
                        if (defaultLocale.equals(locale)) {
                            throw new MessageBundleException(
                                    String.format(
                                            "Locale of [%s] conflicts with the locale [%s] of the default message bundle [%s]",

View on GitHub (pinned to e1c734241f)

Solutions

  1. Give one of the interfaces a distinct @MessageBundle name, e.g. @MessageBundle("admin_msg").
  2. If a dependency provides a bundle with the default name, set an explicit unique name on your own bundle interface.
  3. Delete or consolidate the duplicate bundle interface and update template usages accordingly.

Example fix

// before (conflict: both resolve to "msg")
@MessageBundle public interface Msg { ... }
public class Component { @MessageBundle public interface Msg { ... } }

// after
@MessageBundle public interface Msg { ... }
public class Component { @MessageBundle("component_msg") public interface Msg { ... } }
Defensive patterns

Strategy: validation

Validate before calling

// before build, detect duplicate @MessageBundle names across the project:
// grep -rE '@MessageBundle(\("[^"]+"\))?' --include='*.java' src/ | sort | uniq -d

Prevention

When it happens

Trigger: Two interfaces annotated @MessageBundle with the same explicit value (e.g. both @MessageBundle("msg")); or a top-level bundle interface plus a nested one whose defaulted name collides (a nested interface named Msg with default name 'msg' collides with the default 'msg' of a top-level bundle).

Common situations: Merging modules or refactoring that moved a bundle interface and left a duplicate behind; inheriting a library bundle with the default name 'msg' while defining your own top-level @MessageBundle interface; copy-pasting a bundle interface into a nested class without changing the name.

Related errors


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