quarkusio/quarkus · error · AmbiguousResolutionException
multiple beans with type + type.getName() + found for TLS co
Error message
multiple beans with type + type.getName() + found for TLS configuration + bucketName
What it means
TLS keystore/truststore providers are resolved from the CDI container by type plus Identifier qualifier (the TLS configuration name, or @Default for 'default'). If more than one bean of the requested provider type (e.g. KeystoreProvider/TrustStoreProvider) matches the same configuration name, the resolution is ambiguous and Arc cannot choose, so lookupProvider throws AmbiguousResolutionException.
Source
Thrown at extensions/tls-registry/runtime/src/main/java/io/quarkus/tls/runtime/CertificateRecorder.java:250
@Override
public TlsConfigurationRegistry get() {
return CertificateRecorder.this;
}
};
}
public void register(String name, Supplier<TlsConfiguration> supplier) {
register(name, supplier.get());
}
static <T> InstanceHandle<T> lookupProvider(Class<T> type, String bucketName) {
var container = Arc.container();
var qualifier = TlsConfig.DEFAULT_NAME.equals(bucketName)
? Default.Literal.INSTANCE
: Identifier.Literal.of(bucketName);
var instances = container.listAll(type, qualifier);
if (instances.size() > 1) {
throw new AmbiguousResolutionException(
"multiple beans with type " + type.getName() + " found for TLS configuration " + bucketName);
}
if (instances.isEmpty()) {
return new InstanceHandle<T>() {
@Override
public T get() {
return null;
}
};
}
return instances.get(0);
}
static <T> InstanceHandle<T> lookupFactory(Class<T> type, String typeName) {
var container = Arc.container();
var qualifier = Identifier.Literal.of(typeName);
var instances = container.listAll(type, qualifier);
if (instances.size() > 1) {View on GitHub (pinned to e1c734241f)
Solutions
- Make the bean unique: remove or de-duplicate one of the conflicting provider beans so only one remains per type + identifier.
- Change the @Identifier qualifier on your custom provider to a distinct TLS configuration name and reference that name via tls.*-tls-configuration-name.
- If you must ship a replacement for the default, mark the built-in bean unremovable duplicates carefully — instead exclude the conflicting provider (e.g. via @ExcludeBean or removing the library dependency).
Example fix
// before
@ApplicationScoped
@Identifier("default")
class MyKeyStoreProvider implements KeystoreProvider { ... }
// after
@ApplicationScoped
@Identifier("my-app-ssl")
class MyKeyStoreProvider implements KeystoreProvider { ... }
// and set quarkus.tls.key-store-provider / tls.my-app-ssl references accordingly Defensive patterns
Strategy: validation
Validate before calling
List<InstanceHandle<KeystoreProvider>> existing = Arc.container()
.listAll(KeystoreProvider.class, Identifier.Literal.of("my-app-ssl"));
if (existing.size() > 1) {
throw new IllegalStateException("Duplicate KeystoreProvider beans for identifier 'my-app-ssl'");
} Type guard
boolean hasUniqueProvider(Class<?> type, String bucketName) {
var qualifier = TlsConfig.DEFAULT_NAME.equals(bucketName)
? Default.Literal.INSTANCE : Identifier.Literal.of(bucketName);
return Arc.container().listAll(type, qualifier).size() == 1;
} Try / catch
try {
TlsConfiguration cfg = registry.get("my-app-ssl");
// use cfg
} catch (AmbiguousResolutionException e) {
log.error("Multiple provider beans for this TLS config; check @Identifier qualifiers", e);
} Prevention
- Use unique @Identifier values matching your tls.*-tls-configuration-name exactly.
- Do not annotate custom providers with @Identifier("default") unless intentionally replacing built-ins (and understand the collision risk).
- Grep your classpath/dependencies for duplicate provider implementations before adding a new one.
When it happens
Trigger: Two beans implementing the same provider type annotated @Identifier("<name>") (or both @Default for the default bucket) exist in the container and getKeyStore/getTrustStore calls lookupProvider for that name.
Common situations: Registering a custom KeystoreProvider/TrustStoreProvider with @Identifier("default") while the built-in ones are also active; accidentally duplicating a provider bean in a library and an application; renaming a configuration bucket so two providers now share one identifier.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Multiple instances of %1$s were found for persistence unit %
- Multiple instances of %1$s were found for Hibernate Search i
- Multiple instances of %1$s were found for Hibernate Search b
- Multiple instances of %1$s were found for Hibernate Search i
- Multiple instances of %1$s were found for Hibernate Search S
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/6574d834c06a6f53.
Report an issue: GitHub.