quarkusio/quarkus · error · java.lang.IllegalStateException
Multiple beans found for localized interface [{e.value}] and
Error message
Multiple beans found for localized interface [{e.value}] and locale [{e.key}] What it means
When setting up namespace resolvers, MessageBundles expects exactly one CDI bean per localized interface + locale. If container.select(...) finds multiple matching beans (ambiguous resolution), it throws IllegalStateException('Multiple beans found for localized interface ... and locale ...') instead of guessing.
Source
Thrown at extensions/qute/runtime/src/main/java/io/quarkus/qute/i18n/MessageBundles.java:123
ArcContainer container = Arc.container();
// For every bundle register a new resolver
for (Entry<String, Map<String, Class<?>>> entry : context.get().getBundleInterfaces().entrySet()) {
final String bundleName = entry.getKey();
final Map<String, Resolver> interfaces = new HashMap<>();
Resolver resolver = null;
for (Entry<String, Class<?>> locEntry : entry.getValue().entrySet()) {
if (locEntry.getKey().equals(DEFAULT_LOCALE)) {
resolver = (Resolver) container.select(locEntry.getValue(), Default.Literal.INSTANCE).get();
continue;
}
Instance<?> found = container.select(locEntry.getValue(), new Localized.Literal(locEntry.getKey()));
if (found.isUnsatisfied()) {
throw new IllegalStateException(
Qute.fmt("Bean not found for localized interface [{e.value}] and locale [{e.key}]")
.data("e", locEntry).render());
}
if (found.isAmbiguous()) {
throw new IllegalStateException(
Qute.fmt("Multiple beans found for localized interface [{e.value}] and locale [{e.key}]")
.data("e", locEntry).render());
}
interfaces.put(locEntry.getKey(), (Resolver) found.get());
}
final Resolver defaultResolver = resolver;
builder.addNamespaceResolver(new NamespaceResolver() {
@Override
public CompletionStage<Object> resolve(EvalContext context) {
Object locale = context.getAttribute(ATTRIBUTE_LOCALE);
if (locale == null) {
Object selectedVariant = context.getAttribute(TemplateInstance.SELECTED_VARIANT);
if (selectedVariant != null) {
locale = ((Variant) selectedVariant).getLocale();
}
if (locale == null) {
return defaultResolver.resolve(context);View on GitHub (pinned to e1c734241f)
Solutions
- Remove or rename the duplicate localized bundle so only one bean exists per interface+locale
- Mark one bean @Alternative/@Priority if intentional overriding is needed
- Ensure each @Localized annotation value is unique per bundle interface
Example fix
// before
delete AppMessagesDeCopy.java // duplicate @Localized("de") interface
// after
keep single @Localized("de") AppMessagesDe interface Defensive patterns
Strategy: validation
Validate before calling
// Detect duplicates before startup: at most one @Localized bean per locale per bundle interface
Map<String,Long> dupes = localizedBeans.stream()
.collect(Collectors.groupingBy(b -> b.getAnnotation(Localized.class).value(), Collectors.counting()));
dupes.entrySet().stream().filter(e -> e.getValue() > 1).forEach(e -> {
throw new IllegalStateException("Duplicate @Localized(" + e.getKey() + ") bundle");
}); Try / catch
try {
startNamespaceResolvers();
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Multiple beans found")) {
throw new IllegalStateException("Remove the duplicate @Localized bundle for this locale", e);
}
throw e;
} Prevention
- Enforce one bundle interface per locale per bundle name in code review
- Avoid manually producing beans that implement bundle interfaces
- Use unique @Localized values; never duplicate the same locale string across classes
- Mark intentional overrides with @Alternative and @Priority rather than adding a second bean
When it happens
Trigger: Two or more beans implementing the same bundle interface carry qualifiers that resolve to the same @Localized locale lookup — e.g. duplicate @Localized("de") interfaces, or an implementation bean added alongside the generated bundle bean.
Common situations: Authoring the same localized bundle twice under different class names; a manual @Produces/@Alternative bean colliding with the generated one; copying bundle interfaces between packages creating duplicate @Localized values.
Related errors
- Not a message bundle interface:
- Unable to obtain a message bundle for interface [{ifacename}
- Bean not found for localized interface [{e.value}] and local
- Locale of [%s] conflicts with the locale [%s] of the default
- Cannot register [%s] - a localized message bundle interface
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/933e845fafa07aa3.
Report an issue: GitHub.