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
- 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)
- 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
- Verify BCFIPS version supports the 'DEFAULT' SecureRandom/DRBG algorithm (upgrade bc-fips if needed)
- If FIPS is not actually required, unregister BCFIPS (Security.removeProvider("BCFIPS")) so the code takes the standard NativePRNGNonBlocking path
- 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
- Verify SecureRandom.getInstance("DEFAULT", bcfips) succeeds in a startup health-check when BCFIPS is registered
- Keep bc-fips and its approved companion jars (bcpkix-fips, bcutil-fips) at compatible versions and exclude non-FIPS BC artifacts
- Register BCFIPS with approved-only mode configured before client startup, not lazily at first use
- If FIPS is not a requirement, do not register BCFIPS at all so the NativePRNGNonBlocking path is used
- Pin and test the FIPS configuration in CI to catch version drift early
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
- Unable to find EC Parameter for the given curve oid: ${ecOID
- jcaProvider='${providerName}' does not supply KeyStore type
- jcaProvider='${providerName}' does not supply CertificateFac
- jcaProvider='${providerName}' supplies none of the in-memory
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/2c4b6489b4f46c1c.
Report an issue: GitHub.