apache/pulsar · error · KeyStoreException

jcaProvider='${providerName}' does not supply KeyStore type

Error message

jcaProvider='${providerName}' does not supply KeyStore type '${type}'. Types this provider registers: ${registeredTypes}. Set the store type to one of these (BCFKS is the FIPS-approved format), or unset jcaProvider.

What it means

JcaKeyStores.keyStore(type, jcaProvider) pins KeyStore creation to a specific java.security.Provider. Before delegating it verifies via Provider.getService("KeyStore", type) that the provider actually registers that store type; if not, it throws KeyStoreException listing the types the provider does support (BCFKS being the FIPS-approved choice).

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/JcaKeyStores.java:92

    private JcaKeyStores() {
    }

    /**
     * Create a {@link KeyStore} of the given type, from {@code jcaProvider} when one is pinned.
     *
     * @param type        the store type (e.g. {@code PKCS12}, {@code BCFKS}, {@code JKS})
     * @param jcaProvider the pinned JCA provider, or {@code null} for the JVM provider search order
     * @return an (unloaded) {@link KeyStore} instance
     * @throws KeyStoreException if the type is unavailable — including when a pinned provider does not
     *                           register it (fail loud, with the provider's registered types in the message)
     */
    public static KeyStore keyStore(String type, Provider jcaProvider) throws KeyStoreException {
        if (jcaProvider == null) {
            return KeyStore.getInstance(type);
        }
        if (jcaProvider.getService("KeyStore", type) == null) {
            throw new KeyStoreException("jcaProvider='" + jcaProvider.getName() + "' does not supply KeyStore type '"
                    + type + "'. Types this provider registers: " + registeredTypes(jcaProvider, "KeyStore")
                    + ". Set the store type to one of these (BCFKS is the FIPS-approved format), or unset "
                    + "jcaProvider.");
        }
        return KeyStore.getInstance(type, jcaProvider);
    }

    /**
     * Create an X.509 {@link CertificateFactory}, from {@code jcaProvider} when one is pinned.
     *
     * @param type        the certificate type (in practice {@code X.509})
     * @param jcaProvider the pinned JCA provider, or {@code null} for the JVM provider search order
     * @return the certificate factory
     * @throws CertificateException if the type is unavailable — including when a pinned provider does not
     *                              register it
     */
    public static CertificateFactory certificateFactory(String type, Provider jcaProvider)
            throws CertificateException {

View on GitHub (pinned to 820761864e)

Solutions

  1. Change the configured keystore type to one the provider registers (prefer BCFKS when using BCFIPS)
  2. Convert the keystore file to that type (keytool -importkeystore -srcstoretype JKS -deststoretype BCFKS)
  3. Set jcaProvider to null/omit it so KeyStore.getInstance(type) uses the default provider search
  4. Pin a different provider that does register the requested type

Example fix

// before
KeyStore ks = JcaKeyStores.keyStore("JKS", bcFipsProvider);
// after
KeyStore ks = JcaKeyStores.keyStore("BCFKS", bcFipsProvider);
Defensive patterns

Strategy: validation

Validate before calling

Provider p = ...; String type = "BCFKS";
if (p != null && p.getService("KeyStore", type) == null) {
    throw new IllegalArgumentException("Provider " + p.getName() + " lacks KeyStore type " + type);
}

Type guard

boolean providerHasKeyStoreType(Provider p, String type) { return p == null || p.getService("KeyStore", type) != null; }

Try / catch

try { return JcaKeyStores.keyStore(type, provider); } catch (KeyStoreException e) { log.error("keystore type {} unavailable in provider {}; message: {}", type, provider, e.getMessage()); throw e; }

Prevention

When it happens

Trigger: Calling keyStore("JKS"|"PKCS12"|"BCFKS"|..., bouncyCastleFipsProvider) where the pinned provider lacks that KeyStore service — e.g. requesting JKS from BouncyCastle FIPS, which only registers BCFKS/BCPKCS12-style types.

Common situations: FIPS-mode TLS configuration where tlsRequireValidHostname/store type settings mix JDK default store types with the BC FIPS provider; upgrading to FIPS while keeping legacy keystore files.

Related errors


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