{"record":{"id":"cd89f387a50f2532","repo":"apache/pulsar","slug":"client-tls-configuration-is-invalid-for-purpose-p","errorCode":null,"errorMessage":"Client TLS configuration is invalid for purpose <purpose>: <cause.getMessage()>","messagePattern":"Client TLS configuration is invalid for purpose <purpose>: <cause\\.getMessage\\(\\)>","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/tls/ClientTlsFactorySupport.java","lineNumber":629,"sourceCode":"     * @param factory   the initialized factory\n     * @param purpose   the purpose to probe\n     * @param synthesis the settings baked into a synthesized Netty context on the fallback path\n     */\n    public static void probe(PulsarTlsFactory factory, TlsPurpose purpose, TlsSynthesisSpec synthesis) {\n        try {\n            Optional<TlsHandle<SslContext>> handle =\n                    TlsContextAcquisition.acquireNettyContext(factory, purpose, synthesis).get();\n            if (handle.isEmpty()) {\n                throw new IllegalStateException(\"Client TLS factory \" + factory.getClass().getName()\n                        + \" supplied no Netty SslContext for purpose \" + purpose);\n            }\n            handle.get().dispose();\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new IllegalStateException(\"Interrupted while probing the client TLS factory\", e);\n        } catch (ExecutionException | CompletionException e) {\n            Throwable cause = e.getCause() != null ? e.getCause() : e;\n            throw new IllegalArgumentException(\"Client TLS configuration is invalid for purpose \" + purpose\n                    + \": \" + cause.getMessage(), cause);\n        }\n    }\n\n    private static void initializeBlocking(PulsarTlsFactory factory, TlsFactoryInitContext context)\n            throws Exception {\n        try {\n            factory.initialize(context).get();\n        } catch (ExecutionException e) {\n            Throwable cause = e.getCause() != null ? e.getCause() : e;\n            if (cause instanceof Exception ex) {\n                throw ex;\n            }\n            throw new RuntimeException(cause);\n        }\n    }\n\n    /**","sourceCodeStart":611,"sourceCodeEnd":647,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/tls/ClientTlsFactorySupport.java#L611-L647","documentation":"probe() unwraps ExecutionException/CompletionException from the async TLS context acquisition and rethrows the cause as IllegalArgumentException: \"Client TLS configuration is invalid for purpose <purpose>: <cause message>\". The supplied TLS configuration (keys, certs, truststore, ciphers) failed when the factory tried to build the SslContext.","triggerScenarios":"resolveClientTlsFactory probing a factory whose context build throws: unparseable PEM/PKCS12, missing key file, wrong password, untrusted/self-signed cert chain, unsupported cipher or protocol.","commonSituations":"Wrong tlsKeyFilePath/tlsCertFilePath/tlsTrustCertsFilePath; expired or mismatched certificate and key; wrong keystore password; server cert not signed by configured trust store; Java lacking the required crypto provider.","solutions":["Read the cause message after the colon; it names the concrete TLS problem (file not found, bad password, untrusted cert, etc.).","Fix certificate/key file paths and passwords in the client TLS configuration.","Ensure the server cert chain is signed by a CA in the configured trust store (or enable tlsAllowInsecureConnection only for testing).","Verify cert/key pair match (compare moduli) and are not expired.","Test the factory standalone by calling TlsContextAcquisition directly to reproduce and debug the cause."],"exampleFix":"// before\nString cfg = \"tlsKeyFile=/wrong/path/key.pem,tlsCertFile=/wrong/path/cert.pem\";\n// after\nString cfg = \"tlsKeyFile=/etc/pulsar/key.pem,tlsCertFile=/etc/pulsar/cert.pem,tlsTrustCertsFile=/etc/pulsar/ca.pem\";","handlingStrategy":"validation","validationCode":"void checkTlsInputs(String keyPem, String certPem, String caPem) throws IOException {\n    if (!Files.isReadable(Paths.get(keyPem))) throw new IllegalStateException(\"key unreadable\");\n    if (!Files.isReadable(Paths.get(certPem))) throw new IllegalStateException(\"cert unreadable\");\n    if (!Files.isReadable(Paths.get(caPem))) throw new IllegalStateException(\"ca unreadable\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    ClientTlsFactorySupport.probe(factory, purpose, spec);\n} catch (IllegalArgumentException e) {\n    log.error(\"TLS config invalid: \" + e.getMessage() + \", cause=\" + e.getCause(), e);\n}","preventionTips":["Verify key/cert/truststore file paths and permissions before startup","Check cert expiry and key-cert pairing (matching moduli)","Ensure the server CA is in the client trust store","Log the wrapped cause; it names the exact TLS problem"],"tags":["tls","ssl","certificate","config"],"backgroundTag":"tls-certificate-invalid","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}