apache/pulsar · critical · IllegalStateException

The BCFIPS provider is registered but its DEFAULT SP 800-90A

Error message

The BCFIPS provider is registered but its DEFAULT SP 800-90A DRBG could not be obtained; refusing to fall back to a non-FIPS SecureRandom for data-key and IV generation.

What it means

MessageCryptoBc's static initializer detects that the BCFIPS (Bouncy Castle FIPS) security provider is registered, so it requires its FIPS-approved SP 800-90A DRBG (SecureRandom "DEFAULT" from BCFIPS) for all data-key and GCM IV generation. If SecureRandom.getInstance("DEFAULT", bcfips) throws NoSuchAlgorithmException, the class refuses to fall back to a non-FIPS SecureRandom and throws this IllegalStateException, aborting class initialization. This is a deliberate fail-closed FIPS compliance guard.

Source

Thrown at pulsar-client-messagecrypto-bc/src/main/java/org/apache/pulsar/client/impl/crypto/MessageCryptoBc.java:142

    private static final SecureRandom secureRandom;
    static {
        SecureRandom rand;
        Provider bcfips = Security.getProvider("BCFIPS");
        if (bcfips != null) {
            // When the BC-FIPS provider is registered, source randomness from its SP 800-90A
            // DRBG so data-key and IV generation stays within the FIPS-validated module.
            // Only registered providers are consulted here to avoid triggering BouncyCastle
            // classpath resolution during class loading (see BcProviderHolder above).
            try {
                rand = SecureRandom.getInstance("DEFAULT", bcfips);
            } catch (NoSuchAlgorithmException nsa) {
                // Deliberately fatal rather than falling back: new SecureRandom() resolves by provider
                // search order and may land outside the validated module, which is exactly what this
                // branch exists to prevent. Registering BCFIPS is an operator asking for FIPS-approved
                // randomness, and a data key or GCM IV drawn from anywhere else leaves no trace at run
                // time -- SP 800-38D only permits a random 96-bit GCM IV from an approved DRBG. Failing
                // class initialization surfaces the misconfiguration at the point it can still be fixed.
                throw new IllegalStateException("The BCFIPS provider is registered but its DEFAULT SP "
                        + "800-90A DRBG could not be obtained; refusing to fall back to a non-FIPS "
                        + "SecureRandom for data-key and IV generation.", nsa);
            }
        } else {
            try {
                rand = SecureRandom.getInstance("NativePRNGNonBlocking");
            } catch (NoSuchAlgorithmException nsa) {
                // Unchanged: on a JVM without NativePRNGNonBlocking the platform default is the
                // long-standing behaviour, and no FIPS guarantee was being claimed on this path.
                rand = new SecureRandom();
            }
        }
        secureRandom = rand;

        // Initial seed
        secureRandom.nextBytes(new byte[IV_LEN]);
    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Complete BCFIPS approved-mode setup before loading MessageCryptoBc (install and configure the BC-FIPS approved module, e.g. Security.addProvider(new BouncyCastleFipsProvider()) with approved-only status)
  2. Align all Bouncy Castle artifacts to the FIPS variant at matching versions (bc-fips plus bcpkix-fips/bcutil-fips) and remove conflicting non-FIPS BC jars
  3. Verify BCFIPS version supports the 'DEFAULT' SecureRandom/DRBG algorithm (upgrade bc-fips if needed)
  4. If FIPS is not actually required, unregister BCFIPS (Security.removeProvider("BCFIPS")) so the code takes the standard NativePRNGNonBlocking path
  5. Catch/inspect the cause (NoSuchAlgorithmException) and confirm which DRBG algorithms the installed provider exposes

Example fix

// before: BCFIPS registered but approved module missing
Security.addProvider(new org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider());
// ... later MessageCryptoBc class init fails

// after: register BCFIPS with approved-only mode via bcfips.provider configuration
// (e.g. -Dorg.bouncycastle.fips.approved_only=true) and ensure bc-fips + bcpkix-fips
// on classpath BEFORE instantiating producer/consumer
MessageCryptoBc crypto = new MessageCryptoBc(logCtx, true);
Defensive patterns

Strategy: validation

Validate before calling

// run before touching encrypted producer/consumer
Provider bcfips = Security.getProvider("BCFIPS");
if (bcfips != null) {
    try {
        SecureRandom.getInstance("DEFAULT", bcfips);
    } catch (NoSuchAlgorithmException e) {
        throw new IllegalStateException("BCFIPS registered but DEFAULT DRBG unavailable — "
            + "install/configure the approved BC-FIPS module or remove BCFIPS", e);
    }
}

Type guard

boolean fipsRandomReady() {
    Provider p = Security.getProvider("BCFIPS");
    if (p == null) return true; // non-FIPS path
    try {
        SecureRandom.getInstance("DEFAULT", p);
        return true;
    } catch (NoSuchAlgorithmException e) {
        return false;
    }
}

Try / catch

try {
    Producer<byte[]> producer = client.newProducer().create(); // triggers MessageCryptoBc init
} catch (ExceptionInInitializerError | NoClassDefFoundError e) {
    if (e.getCause() instanceof IllegalStateException
            && e.getCause().getMessage().contains("BCFIPS")) {
        throw new IllegalStateException("FIPS setup broken: BCFIPS provider present but DEFAULT DRBG unavailable", e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: Loading the MessageCryptoBc class when Security.getProvider("BCFIPS") != null but the BCFIPS provider cannot supply its DEFAULT DRBG: BCFIPS jar on classpath without the BC-FIPS approved module (bcpkix/bcfips dependencies) properly approved/initialized, BCFIPS version mismatch, or the provider not yet in an approved state (e.g. missing BouncyCastleFipsApproved status / not approved via Security.setProperty or fips settings).

Common situations: Deploying in FIPS mode where bc-fips jar is present but the approved-only module (bcpkix-fips / bcutil-fips) or its native approval state is missing; mixing non-FIPS BC and FIPS BCFIPS jars; registering BCFIPS programmatically without completing its approved-mode setup; version mismatch after an upgrade.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/2c4b6489b4f46c1c. Report an issue: GitHub.