quarkusio/quarkus · error · MessageBundleException
Default bundle method not found on %s: %s
Error message
Default bundle method not found on %s: %s
What it means
For the default bundle interface (the one declaring @MessageBundle), each method must be mirrored on every localized variant interface so translations line up. When a localized interface method cannot be matched to a method with the same name and parameter types on the default bundle interface, the build fails naming both the bundle interface and the offending method.
Source
Thrown at extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/MessageBundleProcessor.java:1049
cc.method(methodDescOf(method), mc -> {
List<ParamVar> params = new ArrayList<>(method.parametersCount());
for (int i = 0; i < method.parametersCount(); i++) {
String paramName = method.parameterName(i);
params.add(mc.parameter(paramName != null ? paramName : "arg" + i, i));
}
if (!method.returnType().name().equals(DotNames.STRING)) {
throw new MessageBundleException(
String.format("A message bundle method must return java.lang.String: %s#%s",
bundleInterface, method.name()));
}
LOG.debugf("Found message bundle method %s on %s", method, bundleInterface);
AnnotationInstance messageAnnotation;
if (defaultBundleInterface != null) {
MethodInfo defaultBundleMethod = bundleInterfaceWrapper.method(method.name(),
method.parameterTypes().toArray(new Type[] {}));
if (defaultBundleMethod == null) {
throw new MessageBundleException(
String.format("Default bundle method not found on %s: %s", bundleInterface, method));
}
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()));View on GitHub (pinned to e1c734241f)
Solutions
- Make the localized interface's method signature exactly match the default bundle method (same name, same parameter types).
- Remove methods from the localized interface that are not in the default bundle interface.
- Regenerate localized interfaces from the default bundle and re-apply translations.
Example fix
// before
// default: String hello(String name);
@Localized @Locale("de") interface AppMessagesDe extends AppMessages {
String hello(String name, String greeting);
}
// after
@Localized @Locale("de") interface AppMessagesDe extends AppMessages {
@Override
String hello(String name);
} Defensive patterns
Strategy: validation
Validate before calling
// Localized methods must match default bundle signatures
for (java.lang.reflect.Method m : AppMessagesDe.class.getDeclaredMethods()) {
try {
AppMessages.class.getMethod(m.getName(), m.getParameterTypes());
} catch (NoSuchMethodException e) {
throw new IllegalStateException("No matching default method: " + m, e);
}
} Prevention
- Always @Override methods in localized interfaces so mismatches are compile errors
- Change signatures everywhere at once via rename refactoring
- Keep localized interfaces minimal (overrides only)
When it happens
Trigger: A @Localized interface declares a method with a different signature (extra/missing parameter, different types) or an extra method that does not exist on the @MessageBundle interface it extends.
Common situations: Adding a parameter to the base bundle method but only partially updating localized interfaces; hand-writing localized interfaces with divergent signatures; merging translations that added methods present only in one locale interface.
Related errors
- A localized message bundle interface must extend a message b
- @Localized must be declared on an interface: {localized}
- 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
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/5588fcffe8a637f2.
Report an issue: GitHub.