quarkusio/quarkus · error · java.lang.IllegalStateException
Unable to obtain a message bundle for interface [{ifacename}
Error message
Unable to obtain a message bundle for interface [{ifacename}]{#if loc} and locale [{loc.value}]{/if} What it means
MessageBundles.get() obtains the bundle implementation from the CDI container (optionally qualified with @Localized). If no bean is available for the interface (and locale, when a @Localized qualifier is given), it throws IllegalStateException with a Qute-rendered message naming the interface and locale.
Source
Thrown at extensions/qute/runtime/src/main/java/io/quarkus/qute/i18n/MessageBundles.java:55
}
public static <T> T get(Class<T> bundleInterface, Localized localized) {
if (!bundleInterface.isInterface()) {
throw new IllegalArgumentException("Not a message bundle interface: " + bundleInterface.getName());
}
if (!bundleInterface.isAnnotationPresent(MessageBundle.class)
&& !bundleInterface.isAnnotationPresent(Localized.class)) {
throw new IllegalArgumentException(
"Message bundle interface must be annotated either with @MessageBundle or with @Localized: "
+ bundleInterface.getName());
}
ArcContainer container = Arc.requireContainer();
InstanceHandle<T> handle = localized != null ? container.instance(bundleInterface, localized)
: container.instance(bundleInterface);
if (handle.isAvailable()) {
return handle.get();
}
throw new IllegalStateException(Qute.fmt(
"Unable to obtain a message bundle for interface [{ifacename}]{#if loc} and locale [{loc.value}]{/if}")
.data("ifacename", bundleInterface.getName())
.data("loc", localized)
.render());
}
/**
* Obtains a message bundle for the specified interface and the current locale.
* <p>
* The current locale is obtained from a {@link CurrentLocaleProvider} bean. The appropriate localized variant is
* selected by an exact language tag match first, then by a language-only match. If no provider is available, or the
* current locale cannot be determined, or no matching localized variant exists, then the bundle for the default
* locale is returned.
* <p>
* This method backs the beans injected with the {@link LocaleAware} qualifier.
*
* @param <T>
* @param bundleInterfaceView on GitHub (pinned to e1c734241f)
Solutions
- Define a @Localized bean for the requested locale, or request the default bundle without the localized qualifier
- Ensure the interface is annotated with @MessageBundle and part of the Quarkus application build
- Run inside the Quarkus runtime (ArC container started), not a plain JUnit test without @QuarkusTest
- Check quarkus.default-locale / quarkus.locales config to confirm the locale is supported
Example fix
// before
AppMessages m = MessageBundles.get(AppMessages, new Localized.Literal(Locale.FRENCH)); // no fr bundle
// after
@Localized("fr") AppMessagesFr fr; // define/add the fr variant, or use the default bundle
AppMessages m = MessageBundles.get(AppMessages); Defensive patterns
Strategy: try-catch
Validate before calling
// Before calling get(), ensure the app is running under Quarkus and the locale variant exists
boolean defaultOnly = MessageBundles.getHandle == null; // or check Arc.container() != null
Set<String> availableLocales = Set.of("en", "de"); // mirror your @Localized values
if (!availableLocales.contains(requestedLocale)) { /* fall back to default bundle */ } Try / catch
try {
return MessageBundles.get(AppMessages.class, new Localized.Literal(locale));
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Unable to obtain a message bundle")) {
return MessageBundles.get(AppMessages.class); // fall back to default
}
throw e;
} Prevention
- Author @Localized variants for every locale you advertise in quarkus.locales
- Only call MessageBundles.get from within the running Quarkus container (@QuarkusTest or runtime beans)
- Keep a default (unqualified) bundle so lookups without a locale always succeed
When it happens
Trigger: Calling MessageBundles.get(AppMessages.class) (or with a Localized instance) at runtime when the message bundle bean was never registered — e.g. the interface isn't a bean (no @MessageBundle in an unprocessed module), the localized variant for that locale was never defined, or ArC container isn't started.
Common situations: Requesting a locale variant (@Localized('de')) that was never authored; using MessageBundles.get in a non-CDI context/unit test without the Quarkus container; bundle interface living in a library not processed by the Qute extension.
Related errors
- 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
- Not a message bundle interface:
- Multiple beans found for localized interface [{e.value}] and
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/391d1862004c91a4.
Report an issue: GitHub.