{"record":{"id":"7404396b2e4dbdc1","repo":"apache/pulsar","slug":"the-private-key-algorithm-is-not-supported-attemp","errorCode":null,"errorMessage":"The private key algorithm is not supported. attempted: ${failedAlgorithm}","messagePattern":"The private key algorithm is not supported\\. attempted: (.+?)","errorType":"exception","errorClass":"KeyManagementException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/PemReader.java","lineNumber":213,"sourceCode":"            // Stop (and skip) at the last line that has, say, -----END [RSA] PRIVATE KEY-----\n            while ((currentLine = reader.readLine()) != null && !currentLine.startsWith(\"-----END\")) {\n                sb.append(currentLine);\n            }\n            final KeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(sb.toString()));\n            final List<String> failedAlgorithm = new ArrayList<>(KEY_FACTORY_ALGORITHMS.size());\n            for (String algorithm : KEY_FACTORY_ALGORITHMS) {\n                try {\n                    KeyFactory keyFactory = jcaProvider != null ? KeyFactory.getInstance(algorithm, jcaProvider)\n                            : KeyFactory.getInstance(algorithm);\n                    PrivateKey key = keyFactory.generatePrivate(keySpec);\n                    log.debug().attr(\"algorithm\", algorithm).attr(\"provider\", keyFactory.getProvider().getName())\n                            .log(\"Loaded PEM private key\");\n                    return key;\n                } catch (InvalidKeySpecException | NoSuchAlgorithmException ex) {\n                    failedAlgorithm.add(algorithm);\n                }\n            }\n            throw new KeyManagementException(\"The private key algorithm is not supported. attempted: \"\n                    + StringUtils.join(failedAlgorithm, \",\"));\n        } catch (IOException e) {\n            throw new KeyManagementException(\"Private key loading error\", e);\n        }\n\n    }\n}\n","sourceCodeStart":195,"sourceCodeEnd":221,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/PemReader.java#L195-L221","documentation":"PemReader.loadPrivateKeyFromPemStream parses a PEM block and tries each KeyFactory algorithm in KEY_FACTORY_ALGORITHMS to build a PrivateKey from a PKCS8EncodedKeySpec. When every algorithm throws InvalidKeySpecException or NoSuchAlgorithmException, none could decode the key, so it throws KeyManagementException listing the attempted algorithms. This means the PEM content is not a decodable private key of any supported type.","triggerScenarios":"Calling PemReader.loadPrivateKeyFromPemFile/loadPrivateKeyFromPemStream with a PEM whose base64 body does not decode as PKCS8 under any supported KeyFactory algorithm (RSA, EC, etc.); a corrupted/truncated base64 body; an encrypted (password-protected) private key ('ENCRYPTED PRIVATE KEY' or 'BEGIN PRIVATE KEY' with Proc-Type headers that fail decode); a PKCS1 ('BEGIN RSA PRIVATE KEY') body in rare JVM/provider setups; a pinned jcaProvider that supplies none of the algorithms.","commonSituations":"Pointing broker/client TLS config at the wrong file (a certificate instead of a key, or a public key); an openssl-generated key still password-protected; a key in traditional PKCS1 format exported from older tooling; a FIPS or custom Provider lacking RSA/EC KeyFactory support; copy-paste mangling of the PEM body.","solutions":["Verify the file is an unencrypted PKCS#8 PEM ('-----BEGIN PRIVATE KEY-----'); re-export with: openssl pkcs8 -topk8 -nocrypt -in key.pem -out key.pk8.pem","Remove any passphrase protection (openssl rsa -in key.pem) or decrypt before loading; PemReader does not handle encrypted keys","Check that the base64 body between BEGIN/END is intact (no truncation, whitespace corruption, or concatenated blocks)","If passing a pinned jcaProvider, confirm it supports KeyFactory for the key's algorithm (RSA/EC/DSA), or pass null to use the JVM provider search","Inspect the file content: ensure it is not a certificate ('BEGIN CERTIFICATE') or public key ('BEGIN PUBLIC KEY')"],"exampleFix":"// before (PKCS1 key rejected)\nInputStream in = new FileInputStream(\"server-key.pem\"); // -----BEGIN RSA PRIVATE KEY-----\nPrivateKey key = PemReader.loadPrivateKeyFromPemFile(\"server-key.pem\"); // throws\n// after: convert to PKCS8 first\n// $ openssl pkcs8 -topk8 -nocrypt -in server-key.pem -out server-key.pk8.pem\nPrivateKey key = PemReader.loadPrivateKeyFromPemFile(\"server-key.pk8.pem\"); // OK","handlingStrategy":"try-catch","validationCode":"// before calling PemReader\nString pem = Files.readString(Path.of(keyPath));\nif (!pem.contains(\"-----BEGIN\")) throw new IllegalStateException(\"not a PEM file: \" + keyPath);\nif (pem.contains(\"ENCRYPTED\")) throw new IllegalStateException(\"encrypted keys unsupported; decrypt first\");","typeGuard":"static boolean looksLikePkcs8Pem(String pem) {\n    return pem != null && pem.contains(\"-----BEGIN PRIVATE KEY-----\");\n}","tryCatchPattern":"try {\n    PrivateKey key = PemReader.loadPrivateKeyFromPemFile(keyPath);\n} catch (KeyManagementException e) {\n    log.error(\"Cannot load TLS private key {}: {}\", keyPath, e.getMessage());\n    throw new RuntimeException(\"Check key format (PKCS8, unencrypted) and provider support\", e);\n}","preventionTips":["Store keys as unencrypted PKCS#8 PEM ('BEGIN PRIVATE KEY'); convert with openssl pkcs8 -topk8 -nocrypt","Verify the key loads once at startup (fail fast) rather than lazily at first TLS use","Keep certificates and keys in separate, correctly named files","Never reuse a consumed InputStream; open a fresh stream per load","If using a pinned Provider, confirm it registers KeyFactory for RSA/EC"],"tags":["tls","pem","key-management","crypto"],"backgroundTag":"unsupported-private-key-algorithm","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"}