quarkusio/quarkus · critical · ConfigurationException
Security provider %s can not be registered
Error message
Security provider %s can not be registered
What it means
Thrown by SecurityProviderUtils.loadProvider when a configured security provider class (e.g. via quarkus.security.security-providers) cannot be loaded or instantiated. The class is loaded via the thread context loader, instantiated with its no-arg constructor, and cast to java.security.Provider; any failure in that chain is wrapped in a Quarkus ConfigurationException. It is a build/startup-time failure, so the application fails fast.
Source
Thrown at extensions/security/runtime/src/main/java/io/quarkus/security/runtime/SecurityProviderUtils.java:60
public static void insertProvider(Provider provider, int index) {
try {
if (Security.getProvider(provider.getName()) == null) {
Security.insertProviderAt(provider, index);
}
} catch (Exception t) {
final String errorMessage = String.format("Security provider %s can not be inserted", provider.getName());
throw new ConfigurationException(errorMessage, t);
}
}
public static Provider loadProvider(String providerClassName) {
try {
return (Provider) Thread.currentThread().getContextClassLoader().loadClass(providerClassName)
.getDeclaredConstructor().newInstance();
} catch (Exception t) {
final String errorMessage = String.format("Security provider %s can not be registered", providerClassName);
throw new ConfigurationException(errorMessage, t);
}
}
public static Provider loadProviderWithParams(String providerClassName, Class<?>[] paramClasses, Object[] params) {
try {
Constructor<?> c = Thread.currentThread().getContextClassLoader().loadClass(providerClassName)
.getConstructor(paramClasses);
return (Provider) c.newInstance(params);
} catch (Exception t) {
final String errorMessage = String.format("Security provider %s can not be registered", providerClassName);
throw new ConfigurationException(errorMessage, t);
}
}
public static int findProviderIndex(String providerName) {
Provider[] providers = Security.getProviders();
for (int i = 0; i < providers.length; i++) {
if (providerName.equals(providers[i].getName())) {View on GitHub (pinned to e1c734241f)
Solutions
- Verify the fully-qualified provider class name for typos (e.g. org.bouncycastle.jce.provider.BouncyCastleProvider)
- Add the provider artifact as a runtime dependency (e.g. org.bouncycastle:bcprov-jdk18on)
- Confirm the provider has a public no-arg constructor; if it needs parameters use loadProviderWithParams / quarkus.security.security-provider-params instead
- For native builds, register the provider class for reflection or add it via quarkus.native.additional-build-args / runtime reinitialization
- Check the wrapped cause 't' in the exception stack trace for the actual load/instantiation failure
Example fix
// before (pom.xml missing provider) quarkus.security.security-providers=org.bouncycastle.jce.provider.BouncyCastleProvider // after <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> </dependency> quarkus.security.security-providers=org.bouncycastle.jce.provider.BouncyCastleProvider
Defensive patterns
Strategy: validation
Validate before calling
String cls = "org.bouncycastle.jce.provider.BouncyCastleProvider";
try {
Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(cls);
c.getDeclaredConstructor().setAccessible(true);
if (!java.security.Provider.class.isAssignableFrom(c)) throw new IllegalStateException(cls + " is not a Provider");
} catch (ClassNotFoundException | NoSuchMethodException e) {
throw new IllegalStateException("Provider missing or lacks no-arg ctor: " + cls, e);
} Try / catch
try {
SecurityProviderUtils.loadProvider(providerClassName);
} catch (ConfigurationException e) {
log.errorf(e.getCause(), "Cannot load security provider %s", providerClassName);
throw new IllegalStateException("Fix quarkus.security.security-providers entry/dependency", e);
} Prevention
- Keep provider class names in a constant and test-load them in a startup test
- Always add the provider artifact (e.g. bcprov-jdk18on) to the runtime module
- For native images, verify the provider works with -Dnative tests
- Read the ConfigurationException's cause, not just its message
When it happens
Trigger: quarkus.security.security-providers lists a class name that does not exist, is not on the runtime classpath (missing BouncyCastle/other provider dependency), has no public no-arg constructor, or its constructor throws (e.g. native-image restrictions, bad provider self-check).
Common situations: Typo in provider class name (org.bouncycastle.jce.provider.BouncyCastleProvider misspelled); forgot to add the bcprov/bcpkix dependency; provider class present in deployment but not runtime module; GraalVM native image where the provider is not registered for reflection.
Related errors
- Could not obtain credential
- Could not obtain principal
- client-id, client-secret and introspection-url must be confi
- No PropertiesRealmConfig users/roles settings found. Configu
- RuntimeException(e)
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/5b2ab23e06ea2fb3.
Report an issue: GitHub.