apache/pulsar · error · CertificateException
jcaProvider=' ' does not supply CertificateFactory type '…
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.
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=' ' does not supply KeyStore type ' '. Types…
- jcaProvider=' ' supplies none of the in-memory carrier…
- certFilePath must not be null
- Certificate loading error
- keyFilePath must not be null
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/ed04b85b5e68dd83.
Report an issue: GitHub.
Appendix: 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)