quarkusio/quarkus · error · IllegalArgumentException

Namespace [%s] may not be handled by multiple resolvers of t

Error message

Namespace [%s] may not be handled by multiple resolvers of the same priority [%s]: %s and %s

What it means

EngineBuilder.addNamespaceResolver() rejects registering two NamespaceResolvers for the same namespace with equal priority, since resolution would be ambiguous. It validates the namespace first, then scans existing resolvers before adding.

Source

Thrown at independent-projects/qute/core/src/main/java/io/quarkus/qute/EngineBuilder.java:193

     * @see #addSectionHelper(SectionHelperFactory)
     */
    public EngineBuilder addDefaults() {
        return addDefaultSectionHelpers().addDefaultValueResolvers();
    }

    /**
     *
     * @param resolver
     * @return self
     * @throws IllegalArgumentException if there is a resolver of the same priority for the given namespace
     * @see EngineListener
     */
    public EngineBuilder addNamespaceResolver(NamespaceResolver resolver) {
        String namespace = Namespaces.requireValid(resolver.getNamespace());
        for (NamespaceResolver nsResolver : namespaceResolvers) {
            if (nsResolver.getNamespace().equals(namespace)
                    && resolver.getPriority() == nsResolver.getPriority()) {
                throw new IllegalArgumentException(
                        String.format(
                                "Namespace [%s] may not be handled by multiple resolvers of the same priority [%s]: %s and %s",
                                namespace, resolver.getPriority(), nsResolver, resolver));
            }
        }
        this.namespaceResolvers.add(resolver);
        return addListener(resolver);
    }

    /**
     * A {@link Reader} instance produced by a locator is immediately closed right after the template content is parsed.
     *
     * @param locator
     * @return self
     * @see Engine#getTemplate(String)
     */
    public EngineBuilder addLocator(TemplateLocator locator) {
        this.locators.add(locator);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change your resolver's priority via NamespaceResolver.builder().priority(n) so it differs from the conflicting one
  2. Remove the duplicate resolver registration (drop your custom bean if a built-in exists)
  3. Use a different namespace for your custom resolver
  4. Inspect all NamespaceResolver beans/registrations to find which two collide

Example fix

// before: same namespace and default priority as existing
NamespaceResolver.builder().namespace("loc").resolve(ctx -> ...).build();
// after: give it a distinct priority
NamespaceResolver.builder().namespace("loc").priority(10).resolve(ctx -> ...).build();
Defensive patterns

Strategy: validation

Validate before calling

String ns = resolver.getNamespace();
boolean conflicts = engineBuilderKnownResolvers.stream().anyMatch(r ->
    r.getNamespace().equals(ns) && r.getPriority() == resolver.getPriority());
if (conflicts) {
    resolver = NamespaceResolver.builder().namespace(ns).priority(resolver.getPriority() + 1)
        .resolve(resolver).build();
}

Try / catch

try {
    builder.addNamespaceResolver(resolver);
} catch (IllegalArgumentException e) {
    log.warn("Duplicate namespace resolver: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Registering a second resolver whose getNamespace() equals an existing resolver's namespace and whose getPriority() equals the existing one, e.g. via addNamespaceResolver or setupNamespaceResolvers during engine construction.

Common situations: CDI EngineProducer discovering multiple resolver beans for a namespace (e.g. two custom 'loc' resolvers), copy-pasted extensions registering the built-in namespace, or two libraries both providing a resolver for the same namespace at default priority.

Related errors


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