quarkusio/quarkus · error · java.lang.IllegalStateException

Only a single Bouncy Castle registration can be provided.

Error message

Only a single Bouncy Castle registration can be provided.

What it means

Quarkus supports registering the Bouncy Castle security provider either via quarkus.security.security-providers=bc / bcjsse or via explicit dependencies/extensions, but only one registration path per provider kind. SecurityProcessor.getOne() enforces that at most one build item of a given Bouncy Castle registration type exists; more than one means conflicting registrations were detected during the build.

Source

Thrown at extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java:627

        boolean isInFipsMode;

        Optional<BouncyCastleJsseProviderBuildItem> bouncyCastleJsseProvider = getOne(bouncyCastleJsseProviders);
        if (bouncyCastleJsseProvider.isPresent()) {
            isInFipsMode = bouncyCastleJsseProvider.get().isInFipsMode();
        } else {
            Optional<BouncyCastleProviderBuildItem> bouncyCastleProvider = getOne(bouncyCastleProviders);
            isInFipsMode = bouncyCastleProvider.isPresent() && bouncyCastleProvider.get().isInFipsMode();
        }

        if (isInFipsMode) {
            jpmsExports.produce(new JPMSExportBuildItem("java.base", "sun.security.internal.spec"));
            jpmsExports.produce(new JPMSExportBuildItem("java.base", "sun.security.provider"));
        }
    }

    private static <BI extends MultiBuildItem> Optional<BI> getOne(List<BI> items) {
        if (items.size() > 1) {
            throw new IllegalStateException("Only a single Bouncy Castle registration can be provided.");
        }
        return items.stream().findFirst();
    }

    /**
     * Determine the classes that make up the provider and its services
     *
     * @param providerName - JCA provider name
     * @return class names that make up the provider and its services
     */
    private static List<String> registerProvider(String providerName,
            List<String> providerConfigs,
            BuildProducer<NativeImageSecurityProviderBuildItem> additionalProviders) {
        List<String> providerClasses = new ArrayList<>();
        Provider provider = Security.getProvider(providerName);
        if (provider != null) {
            providerClasses.add(provider.getClass().getName());
            for (Provider.Service service : provider.getServices()) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove the duplicate registration: keep either quarkus.security.security-providers=bc (or bcjsse) or the explicit dependency-based registration, not both.
  2. Check all application.properties/application-*.properties files for duplicated security-providers entries.
  3. Inspect which extensions/dependencies bring in a BC registration and drop the redundant one.

Example fix

# before
quarkus.security.security-providers=bc
quarkus.security.security-providers=bcjsse

# after
quarkus.security.security-providers=bcjsse
Defensive patterns

Strategy: validation

Validate before calling

# ensure only one BC registration exists
# grep all config files:
grep -rn "security-providers" src/main/resources src/test/resources

Prevention

When it happens

Trigger: Both the quarkus-security extension's automatic BC registration (config property) and an explicit Bouncy Castle registration (e.g. custom extension or another provider-affecting config) are present at the same time; or the bc and bcjsse configurations overlap producing two build items of the same type.

Common situations: Setting quarkus.security.security-providers=bc while also adding a Bouncy Castle JSSE configuration; migrating config and leaving duplicate entries in application.properties and profile-specific files (test/prod profiles).

Related errors


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