apache/pulsar · error · CertificateException
jcaProvider='${providerName}' does not supply CertificateFac
Error message
jcaProvider='${providerName}' does not supply CertificateFactory type '${type}'. Types this provider registers: ${registeredTypes}. Unset jcaProvider, or pin a provider that supplies X.509 certificates. What it means
JcaKeyStores.certificateFactory(type, jcaProvider) pins CertificateFactory creation to a given Provider and first checks provider.getService("CertificateFactory", type). If the pinned provider does not register that certificate type (typically X.509), it throws CertificateException naming the provider and its registered types.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/JcaKeyStores.java:115
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 {
if (jcaProvider == null) {
return CertificateFactory.getInstance(type);
}
if (jcaProvider.getService("CertificateFactory", type) == null) {
throw new CertificateException("jcaProvider='" + jcaProvider.getName() + "' does not supply "
+ "CertificateFactory type '" + type + "'. Types this provider registers: "
+ registeredTypes(jcaProvider, "CertificateFactory") + ". Unset jcaProvider, or pin a provider "
+ "that supplies X.509 certificates.");
}
return CertificateFactory.getInstance(type, jcaProvider);
}
/**
* 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 {View on GitHub (pinned to 820761864e)
Solutions
- Pin a provider that supplies X.509 CertificateFactory services (e.g. BouncyCastle BC/BCFIPS with the cert-path services registered)
- Pass null as jcaProvider to use the JDK default provider
- Register the missing service in your custom provider configuration
Example fix
// before
CertificateFactory cf = JcaKeyStores.certificateFactory("X.509", bcFipsJcaProvider); // provider lacks X.509
// after
CertificateFactory cf = JcaKeyStores.certificateFactory("X.509", null); // or use a provider registering X.509 Defensive patterns
Strategy: validation
Validate before calling
Provider p = ...;
if (p != null && p.getService("CertificateFactory", "X.509") == null) {
throw new IllegalArgumentException("Provider " + p.getName() + " lacks CertificateFactory X.509");
} Type guard
boolean providerHasX509CertFactory(Provider p) { return p == null || p.getService("CertificateFactory", "X.509") != null; } Try / catch
try { return JcaKeyStores.certificateFactory("X.509", provider); } catch (CertificateException e) { log.error("X.509 CertificateFactory unavailable in provider {}: {}", provider, e.getMessage()); throw e; } Prevention
- Only pin providers that register CertificateFactory.X.509 (BouncyCastle/BCFIPS do)
- Pass null jcaProvider unless you specifically need a non-default provider
- Verify provider capabilities with getService() before wiring TLS config
- Keep bc-fips/bcpkix versions consistent with your FIPS mode
When it happens
Trigger: Calling certificateFactory("X.509", provider) where the provider (e.g. a JCA-only BCFIPS provider without the X.509 CertFactory service, or a narrowly scoped provider) lacks the CertificateFactory.X.509 service.
Common situations: FIPS TLS setup where the jcaProvider is pinned but does not supply X.509 certificate parsing; PEM certificate loading (PemReader) with a mis-pinned provider.
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
- jcaProvider='${providerName}' supplies none of the in-memory
- certFilePath must not be null
- keyFilePath must not be null
- Passed in parameter empty. KEYSTORE_PATH: ${keyStorePath} KE
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/ed04b85b5e68dd83.
Report an issue: GitHub.