{"record":{"id":"d606ff8c23ad25d8","repo":"apache/pulsar","slug":"private-key-loading-error","errorCode":null,"errorMessage":"Private key loading error","messagePattern":"Private key loading error","errorType":"exception","errorClass":"KeyManagementException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/PemReader.java","lineNumber":149,"sourceCode":"     * Load a PKCS#8 PEM private key, manufacturing the key object with a pinned JCA provider.\n     *\n     * @param keyFilePath the PEM file path\n     * @param jcaProvider the pinned JCA provider, or {@code null} for the JVM provider search order\n     * @return the loaded private key, or {@code null} when no path was given\n     * @throws KeyManagementException if the key cannot be loaded\n     */\n    public static PrivateKey loadPrivateKeyFromPemFile(String keyFilePath, Provider jcaProvider)\n            throws KeyManagementException {\n        if (keyFilePath == null || keyFilePath.isEmpty()) {\n            return null;\n        }\n\n        PrivateKey privateKey;\n\n        try (FileInputStream input = new FileInputStream(keyFilePath)) {\n            privateKey = loadPrivateKeyFromPemStream(input, jcaProvider);\n        } catch (IOException e) {\n            throw new KeyManagementException(\"Private key loading error\", e);\n        }\n\n        return privateKey;\n    }\n\n    public static PrivateKey loadPrivateKeyFromPemStream(InputStream inStream) throws KeyManagementException {\n        return loadPrivateKeyFromPemStream(inStream, null);\n    }\n\n    /**\n     * Load a PKCS#8 PEM private key from a stream, manufacturing the key object with a pinned JCA provider.\n     *\n     * <p>The existing per-algorithm loop degrades naturally: an algorithm the pinned provider does not supply\n     * is skipped like an algorithm that does not match the key, and the same loud \"algorithm is not supported\"\n     * error is thrown when none of them works.\n     *\n     * @param inStream    the PEM stream\n     * @param jcaProvider the pinned JCA provider, or {@code null} for the JVM provider search order","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/PemReader.java#L131-L167","documentation":"PemReader.loadPrivateKeyFromPemFile reads the PEM private-key file and delegates to loadPrivateKeyFromPemStream. Any IOException while reading the file (missing file, permissions, I/O failure) is wrapped into KeyManagementException('Private key loading error').","triggerScenarios":"Key file path is wrong or the file does not exist (FileNotFoundException); process lacks read permission on the key file; I/O error while streaming (truncated file, failing volume).","commonSituations":"Misconfigured tlsKeyFilePath on broker/client; Kubernetes secret not mounted or wrong mount path; key file rotated/renamed while the process held a stale path; running in a hardened container where the secret file permissions are too restrictive.","solutions":["Verify the key file path exists and is readable (ls -l, container mounts, secret names)","Fix the configured tlsKeyFilePath / mount the secret volume correctly","Check the wrapped cause in the stack trace to confirm it is I/O vs parsing (parsing failures are raised by loadPrivateKeyFromPemStream instead)","Ensure the key is in a PEM format the reader supports (unencrypted PKCS#8/SEC1) and permissions are e.g. 600 for the service user"],"exampleFix":"// before\ntlsKeyFilePath=/secrets/broker.key.pem   // secret not mounted\n// after\n// mount the secret and set readable perms:\n// chmod 600 /secrets/broker.key.pem\nFile f = new File(path);\nif (!f.canRead()) throw new IllegalStateException(\"key file missing: \" + path);","handlingStrategy":"try-catch","validationCode":"File f = new File(keyPath);\nif (!f.isFile() || !f.canRead()) throw new IllegalStateException(\"Unreadable key file: \" + keyPath);","typeGuard":null,"tryCatchPattern":"try { return PemReader.loadPrivateKeyFromPemFile(path); } catch (KeyManagementException e) { log.error(\"Failed loading private key from {}: {}\", path, e.getCause()); throw new IllegalStateException(\"Invalid TLS key configuration\", e); }","preventionTips":["Check key file path and read permissions (mode 600 for the service user) before startup","Ensure secrets are actually mounted in container/Kubernetes deployments","Distinguish I/O failures (this error) from parse failures raised by loadPrivateKeyFromPemStream via e.getCause()","Use unencrypted PEM private keys in a supported format (PKCS#8/SEC1)","Add a config pre-flight check that opens and reads both cert and key files"],"tags":["java","tls","pem","private-key","io"],"backgroundTag":"private-key-loading-error","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"}