apache/pulsar · error · KeyStoreException
jcaProvider='${providerName}' supplies none of the in-memory
Error message
jcaProvider='${providerName}' supplies none of the in-memory carrier keystore types ${IN_MEMORY_STORE_TYPE_PREFERENCE} needed to build the TLS key managers. Types this provider registers: ${registeredTypes}. Unset jcaProvider, or pin a provider that supplies BCFKS or PKCS12. What it means
JcaKeyStores.inMemoryStoreType(jcaProvider) selects an in-memory keystore carrier type (BCFKS, then PKCS12, per IN_MEMORY_STORE_TYPE_PREFERENCE) to build TLS key managers. If the pinned provider registers none of the preferred types, it throws KeyStoreException — the key managers cannot be built with that provider.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/JcaKeyStores.java:142
* Choose the store type for a process-local in-memory carrier keystore: with no pinned provider the
* caller's current default ({@code defaultType}, i.e. today's behaviour), otherwise the first
* {@link #IN_MEMORY_STORE_TYPE_PREFERENCE preferred} type the pinned provider actually registers.
*
* @param jcaProvider the pinned JCA provider, or {@code null}
* @param defaultType the type to use when no provider is pinned
* @return the carrier store type
* @throws KeyStoreException if the pinned provider registers none of the preferred carrier types
*/
public static String inMemoryStoreType(Provider jcaProvider, String defaultType) throws KeyStoreException {
if (jcaProvider == null) {
return defaultType;
}
for (String candidate : IN_MEMORY_STORE_TYPE_PREFERENCE) {
if (jcaProvider.getService("KeyStore", candidate) != null) {
return candidate;
}
}
throw new KeyStoreException("jcaProvider='" + jcaProvider.getName() + "' supplies none of the in-memory "
+ "carrier keystore types " + IN_MEMORY_STORE_TYPE_PREFERENCE + " needed to build the TLS key "
+ "managers. Types this provider registers: " + registeredTypes(jcaProvider, "KeyStore")
+ ". Unset jcaProvider, or pin a provider that supplies BCFKS or PKCS12.");
}
/**
* Generate a random, per-instance password for a process-local in-memory carrier keystore.
*
* <p>The carrier's key entries used to be stored under an empty password. PKCS12 (and BCFKS) protect key
* entries with a password-based KDF, and a FIPS provider in approved-only mode enforces SP 800-132
* constraints on that KDF — a minimum password length among them — so an empty password can be rejected
* outright at context-build time. The password is generated, used, and (by the caller) zeroed within a
* single build; it is never persisted, logged, or compared.
*
* @return a freshly generated password
*/
public static char[] newInMemoryPassword() {
char[] password = new char[IN_MEMORY_PASSWORD_LENGTH];View on GitHub (pinned to 820761864e)
Solutions
- Pin a provider that registers BCFKS or PKCS12 KeyStore services (e.g. BouncyCastle FIPS)
- Unset jcaProvider so the JDK default providers are used
- Add BouncyCastle (bc-fips) to the classpath and register it before building the TLS context
Example fix
// before Security.addProvider(new org.bouncycastle.jce.provider.BouncyJetProvider()); // wrong/none // after Security.addProvider(new org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider()); String type = JcaKeyStores.inMemoryStoreType(bcFipsProvider); // resolves BCFKS
Defensive patterns
Strategy: validation
Validate before calling
boolean ok = Stream.of("BCFKS", "PKCS12").anyMatch(t -> provider != null && provider.getService("KeyStore", t) != null);
if (!ok) throw new IllegalArgumentException("Provider lacks in-memory keystore types"); Type guard
boolean supportsInMemoryKeyStore(Provider p) { return p != null && (p.getService("KeyStore", "BCFKS") != null || p.getService("KeyStore", "PKCS12") != null); } Try / catch
try { String type = JcaKeyStores.inMemoryStoreType(provider); } catch (KeyStoreException e) { log.error("provider {} cannot build TLS key managers: {}", provider, e.getMessage()); throw e; } Prevention
- Use BouncyCastle FIPS provider, which registers BCFKS, for in-memory TLS stores
- Unset jcaProvider if you don't need provider pinning
- Check provider services at startup with a fail-fast configuration validator
- Keep the bc-fips jar on the classpath in all deployment images
When it happens
Trigger: Calling inMemoryStoreType(provider) or the TLS setup that uses it, when provider.getService("KeyStore", candidate) returns null for every candidate in IN_MEMORY_STORE_TYPE_PREFERENCE (BCFKS, PKCS12).
Common situations: FIPS deployments pinning a minimal provider that only registers BCFKS-less subsets; custom or embedded JVMs with stripped security providers.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- jcaProvider='${providerName}' does not supply KeyStore type
- Passed in parameter empty. KEYSTORE_PATH: ${keyStorePath} KE
- jcaProvider='${providerName}' does not supply CertificateFac
- certFilePath must not be null
- keyFilePath must not be null
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/a483fbd517632453.
Report an issue: GitHub.