apache/pulsar · error · KeyStoreException

jcaProvider=' ' does not supply KeyStore type ' '. Types…

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).

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.

Appendix: 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)