quarkusio/quarkus · error · MessageBundleException

Message bundle name [%s] declared on %s must be a valid name

Error message

Message bundle name [%s] declared on %s must be a valid namespace - the value can only consist of alphanumeric characters and underscores

What it means

MessageBundleException thrown at build time by MessageBundleProcessor when the name given in @MessageBundle (or a defaulted name derived from nested class names) is not a valid Qute namespace. A bundle name becomes the template namespace (e.g. {msg:hello()}), so it may contain only alphanumeric characters and underscores. An invalid name would produce unreachable or malformed template expressions, so the build fails fast.

Source

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

                            // declaring classes in the hierarchy separated by underscores
                            List<String> names = new ArrayList<>();
                            names.add(bundleClass.simpleName());
                            DotName enclosingName = bundleClass.enclosingClass();
                            while (enclosingName != null) {
                                ClassInfo enclosingClass = index.getClassByName(enclosingName);
                                if (enclosingClass != null) {
                                    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);
                    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Rename the bundle to only alphanumeric/underscore characters, e.g. @MessageBundle(value = "app_messages").
  2. If relying on the default name, move the interface to top level (name becomes 'msg') or rename enclosing/nested classes so the derived name is valid.
  3. Update all templates using the old namespace (e.g. {app-bundle:key} -> {app_messages:key}).

Example fix

// before
@MessageBundle(value = "app-messages")
public interface AppMessages { @Message String hello(); }

// after
@MessageBundle(value = "app_messages")
public interface AppMessages { @Message String hello(); }
Defensive patterns

Strategy: validation

Validate before calling

String name = bundleAnnotation.value();
if (name != null && !name.matches("[A-Za-z0-9_]+")) {
    throw new IllegalArgumentException("Bundle name must be alphanumeric/underscore: " + name);
}

Prevention

When it happens

Trigger: Annotating an interface with @MessageBundle(value = "my-bundle") (hyphen, dot, space or other non-alphanumeric characters), or a nested interface whose auto-derived name joins enclosing class simple names with underscores producing characters outside [alnum_].

Common situations: Using kebab-case names by habit (e.g. "app-messages"); copying names with dots like "app.messages"; putting locale suffixes into the name; nesting bundle interfaces inside inner classes and assuming any name works.

Related errors


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