{"record":{"id":"3a7e087144147ff4","repo":"apache/pulsar","slug":"keyfilepath-must-not-be-null","errorCode":null,"errorMessage":"keyFilePath must not be null","messagePattern":"keyFilePath must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationDataTls.java","lineNumber":56,"sourceCode":"public class AuthenticationDataTls implements AuthenticationDataProvider {\n    private static final long serialVersionUID = 1L;\n    protected X509Certificate[] tlsCertificates;\n    protected PrivateKey tlsPrivateKey;\n    private transient FileModifiedTimeUpdater certFile, keyFile;\n    // key and cert using stream\n    private transient InputStream certStream, keyStream;\n    @SuppressFBWarnings(value = \"SE_TRANSIENT_FIELD_NOT_RESTORED\",\n            justification = \"Using custom serializer which Findbugs can't detect\")\n    private transient Supplier<ByteArrayInputStream> certStreamProvider, keyStreamProvider, trustStoreStreamProvider;\n    private static final Map<String, String> headers = Collections.singletonMap(\n            PULSAR_AUTH_METHOD_NAME, AuthenticationTls.AUTH_METHOD_NAME);\n\n    public AuthenticationDataTls(String certFilePath, String keyFilePath) throws KeyManagementException {\n        if (certFilePath == null) {\n            throw new IllegalArgumentException(\"certFilePath must not be null\");\n        }\n        if (keyFilePath == null) {\n            throw new IllegalArgumentException(\"keyFilePath must not be null\");\n        }\n        this.certFile = new FileModifiedTimeUpdater(certFilePath);\n        this.keyFile = new FileModifiedTimeUpdater(keyFilePath);\n        this.tlsCertificates = PemReader.loadCertificatesFromPemFile(certFilePath);\n        this.tlsPrivateKey = PemReader.loadPrivateKeyFromPemFile(keyFilePath);\n    }\n\n    public AuthenticationDataTls(Supplier<ByteArrayInputStream> certStreamProvider,\n            Supplier<ByteArrayInputStream> keyStreamProvider) throws KeyManagementException {\n        this(certStreamProvider, keyStreamProvider, null);\n    }\n\n    public AuthenticationDataTls(Supplier<ByteArrayInputStream> certStreamProvider,\n            Supplier<ByteArrayInputStream> keyStreamProvider, Supplier<ByteArrayInputStream> trustStoreStreamProvider)\n            throws KeyManagementException {\n        if (certStreamProvider == null || certStreamProvider.get() == null) {\n            throw new IllegalArgumentException(\"certStream provider or stream must not be null\");\n        }","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationDataTls.java#L38-L74","documentation":"The AuthenticationDataTls(String certFilePath, String keyFilePath) constructor throws IllegalArgumentException when keyFilePath is null. TLS authentication needs both the client certificate chain and the private key; a null key path means no private key can be loaded, so the constructor rejects it before any file I/O.","triggerScenarios":"Constructing AuthenticationDataTls with a null second argument, e.g. AuthenticationTls configured without the tlsKeyFile auth parameter, or a key path variable left unassigned.","commonSituations":"authParams JSON missing 'tlsKeyFile'; private key mounted under a different name than expected; splitting cert/key config across files where only the cert section was migrated; typo'd key name ('tlsKeyfile') silently yielding null.","solutions":["Provide the PEM private key path (AuthenticationTls 'tlsKeyFile' auth param) to the constructor.","Check the exact authParams key names — 'tlsCertFile' and 'tlsKeyFile' — for typos.","Validate both paths non-null before constructing the authentication data at startup."],"exampleFix":"// before\nparams: {\"tlsCertFile\": \"/certs/client-cert.pem\"} // tlsKeyFile missing -> null\n// after\nparams: {\"tlsCertFile\": \"/certs/client-cert.pem\", \"tlsKeyFile\": \"/certs/client-key.pem\"}","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(keyFilePath, \"TLS key file path (tlsKeyFile) must be configured\");\nif (!new File(keyFilePath).canRead()) throw new IllegalStateException(\"key file not readable: \" + keyFilePath);","typeGuard":null,"tryCatchPattern":"try {\n    authData = new AuthenticationDataTls(certFilePath, keyFilePath);\n} catch (IllegalArgumentException | KeyManagementException e) {\n    log.error(\"TLS auth misconfigured: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Always set the 'tlsKeyFile' auth parameter alongside 'tlsCertFile'.","Check authParams key spelling exactly (tlsKeyFile, not tlsKeyfile).","Validate both cert and key paths at startup before creating the PulsarClient."],"tags":["java","tls","authentication","configuration","pulsar-client"],"backgroundTag":"missing-tls-certificate","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"}