apache/pulsar · error · IllegalArgumentException

Client TLS configuration is invalid for purpose <purpose>: <

Error message

Client TLS configuration is invalid for purpose <purpose>: <cause.getMessage()>

What it means

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.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/tls/ClientTlsFactorySupport.java:629

     * @param factory   the initialized factory
     * @param purpose   the purpose to probe
     * @param synthesis the settings baked into a synthesized Netty context on the fallback path
     */
    public static void probe(PulsarTlsFactory factory, TlsPurpose purpose, TlsSynthesisSpec synthesis) {
        try {
            Optional<TlsHandle<SslContext>> handle =
                    TlsContextAcquisition.acquireNettyContext(factory, purpose, synthesis).get();
            if (handle.isEmpty()) {
                throw new IllegalStateException("Client TLS factory " + factory.getClass().getName()
                        + " supplied no Netty SslContext for purpose " + purpose);
            }
            handle.get().dispose();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IllegalStateException("Interrupted while probing the client TLS factory", e);
        } catch (ExecutionException | CompletionException e) {
            Throwable cause = e.getCause() != null ? e.getCause() : e;
            throw new IllegalArgumentException("Client TLS configuration is invalid for purpose " + purpose
                    + ": " + cause.getMessage(), cause);
        }
    }

    private static void initializeBlocking(PulsarTlsFactory factory, TlsFactoryInitContext context)
            throws Exception {
        try {
            factory.initialize(context).get();
        } catch (ExecutionException e) {
            Throwable cause = e.getCause() != null ? e.getCause() : e;
            if (cause instanceof Exception ex) {
                throw ex;
            }
            throw new RuntimeException(cause);
        }
    }

    /**

View on GitHub (pinned to 820761864e)

Solutions

  1. Read the cause message after the colon; it names the concrete TLS problem (file not found, bad password, untrusted cert, etc.).
  2. Fix certificate/key file paths and passwords in the client TLS configuration.
  3. Ensure the server cert chain is signed by a CA in the configured trust store (or enable tlsAllowInsecureConnection only for testing).
  4. Verify cert/key pair match (compare moduli) and are not expired.
  5. Test the factory standalone by calling TlsContextAcquisition directly to reproduce and debug the cause.

Example fix

// before
String cfg = "tlsKeyFile=/wrong/path/key.pem,tlsCertFile=/wrong/path/cert.pem";
// after
String cfg = "tlsKeyFile=/etc/pulsar/key.pem,tlsCertFile=/etc/pulsar/cert.pem,tlsTrustCertsFile=/etc/pulsar/ca.pem";
Defensive patterns

Strategy: validation

Validate before calling

void checkTlsInputs(String keyPem, String certPem, String caPem) throws IOException {
    if (!Files.isReadable(Paths.get(keyPem))) throw new IllegalStateException("key unreadable");
    if (!Files.isReadable(Paths.get(certPem))) throw new IllegalStateException("cert unreadable");
    if (!Files.isReadable(Paths.get(caPem))) throw new IllegalStateException("ca unreadable");
}

Try / catch

try {
    ClientTlsFactorySupport.probe(factory, purpose, spec);
} catch (IllegalArgumentException e) {
    log.error("TLS config invalid: " + e.getMessage() + ", cause=" + e.getCause(), e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/cd89f387a50f2532. Report an issue: GitHub.