{"record":{"id":"ed04b85b5e68dd83","repo":"apache/pulsar","slug":"jcaprovider-providername-does-not-supply-cert","errorCode":null,"errorMessage":"jcaProvider='${providerName}' does not supply CertificateFactory type '${type}'. Types this provider registers: ${registeredTypes}. Unset jcaProvider, or pin a provider that supplies X.509 certificates.","messagePattern":"jcaProvider='(.+?)' does not supply CertificateFactory type '(.+?)'\\. Types this provider registers: (.+?)\\. Unset jcaProvider, or pin a provider that supplies X\\.509 certificates\\.","errorType":"exception","errorClass":"CertificateException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/JcaKeyStores.java","lineNumber":115,"sourceCode":"        return KeyStore.getInstance(type, jcaProvider);\n    }\n\n    /**\n     * Create an X.509 {@link CertificateFactory}, from {@code jcaProvider} when one is pinned.\n     *\n     * @param type        the certificate type (in practice {@code X.509})\n     * @param jcaProvider the pinned JCA provider, or {@code null} for the JVM provider search order\n     * @return the certificate factory\n     * @throws CertificateException if the type is unavailable — including when a pinned provider does not\n     *                              register it\n     */\n    public static CertificateFactory certificateFactory(String type, Provider jcaProvider)\n            throws CertificateException {\n        if (jcaProvider == null) {\n            return CertificateFactory.getInstance(type);\n        }\n        if (jcaProvider.getService(\"CertificateFactory\", type) == null) {\n            throw new CertificateException(\"jcaProvider='\" + jcaProvider.getName() + \"' does not supply \"\n                    + \"CertificateFactory type '\" + type + \"'. Types this provider registers: \"\n                    + registeredTypes(jcaProvider, \"CertificateFactory\") + \". Unset jcaProvider, or pin a provider \"\n                    + \"that supplies X.509 certificates.\");\n        }\n        return CertificateFactory.getInstance(type, jcaProvider);\n    }\n\n    /**\n     * Choose the store type for a process-local in-memory carrier keystore: with no pinned provider the\n     * caller's current default ({@code defaultType}, i.e. today's behaviour), otherwise the first\n     * {@link #IN_MEMORY_STORE_TYPE_PREFERENCE preferred} type the pinned provider actually registers.\n     *\n     * @param jcaProvider the pinned JCA provider, or {@code null}\n     * @param defaultType the type to use when no provider is pinned\n     * @return the carrier store type\n     * @throws KeyStoreException if the pinned provider registers none of the preferred carrier types\n     */\n    public static String inMemoryStoreType(Provider jcaProvider, String defaultType) throws KeyStoreException {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/JcaKeyStores.java#L97-L133","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nCertificateFactory cf = JcaKeyStores.certificateFactory(\"X.509\", bcFipsJcaProvider); // provider lacks X.509\n// after\nCertificateFactory cf = JcaKeyStores.certificateFactory(\"X.509\", null); // or use a provider registering X.509","handlingStrategy":"validation","validationCode":"Provider p = ...;\nif (p != null && p.getService(\"CertificateFactory\", \"X.509\") == null) {\n    throw new IllegalArgumentException(\"Provider \" + p.getName() + \" lacks CertificateFactory X.509\");\n}","typeGuard":"boolean providerHasX509CertFactory(Provider p) { return p == null || p.getService(\"CertificateFactory\", \"X.509\") != null; }","tryCatchPattern":"try { return JcaKeyStores.certificateFactory(\"X.509\", provider); } catch (CertificateException e) { log.error(\"X.509 CertificateFactory unavailable in provider {}: {}\", provider, e.getMessage()); throw e; }","preventionTips":["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"],"tags":["java","tls","certificates","fips","configuration"],"backgroundTag":"provider-missing-certificatefactory-type","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}