apache/pulsar · error · KeyManagementException

The private key algorithm is not supported. attempted: ${fai

Error message

The private key algorithm is not supported. attempted: ${failedAlgorithm}

What it means

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.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/tls/PemReader.java:213

            // Stop (and skip) at the last line that has, say, -----END [RSA] PRIVATE KEY-----
            while ((currentLine = reader.readLine()) != null && !currentLine.startsWith("-----END")) {
                sb.append(currentLine);
            }
            final KeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(sb.toString()));
            final List<String> failedAlgorithm = new ArrayList<>(KEY_FACTORY_ALGORITHMS.size());
            for (String algorithm : KEY_FACTORY_ALGORITHMS) {
                try {
                    KeyFactory keyFactory = jcaProvider != null ? KeyFactory.getInstance(algorithm, jcaProvider)
                            : KeyFactory.getInstance(algorithm);
                    PrivateKey key = keyFactory.generatePrivate(keySpec);
                    log.debug().attr("algorithm", algorithm).attr("provider", keyFactory.getProvider().getName())
                            .log("Loaded PEM private key");
                    return key;
                } catch (InvalidKeySpecException | NoSuchAlgorithmException ex) {
                    failedAlgorithm.add(algorithm);
                }
            }
            throw new KeyManagementException("The private key algorithm is not supported. attempted: "
                    + StringUtils.join(failedAlgorithm, ","));
        } catch (IOException e) {
            throw new KeyManagementException("Private key loading error", e);
        }

    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. 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
  2. Remove any passphrase protection (openssl rsa -in key.pem) or decrypt before loading; PemReader does not handle encrypted keys
  3. Check that the base64 body between BEGIN/END is intact (no truncation, whitespace corruption, or concatenated blocks)
  4. 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
  5. Inspect the file content: ensure it is not a certificate ('BEGIN CERTIFICATE') or public key ('BEGIN PUBLIC KEY')

Example fix

// before (PKCS1 key rejected)
InputStream in = new FileInputStream("server-key.pem"); // -----BEGIN RSA PRIVATE KEY-----
PrivateKey key = PemReader.loadPrivateKeyFromPemFile("server-key.pem"); // throws
// after: convert to PKCS8 first
// $ openssl pkcs8 -topk8 -nocrypt -in server-key.pem -out server-key.pk8.pem
PrivateKey key = PemReader.loadPrivateKeyFromPemFile("server-key.pk8.pem"); // OK
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling PemReader
String pem = Files.readString(Path.of(keyPath));
if (!pem.contains("-----BEGIN")) throw new IllegalStateException("not a PEM file: " + keyPath);
if (pem.contains("ENCRYPTED")) throw new IllegalStateException("encrypted keys unsupported; decrypt first");

Type guard

static boolean looksLikePkcs8Pem(String pem) {
    return pem != null && pem.contains("-----BEGIN PRIVATE KEY-----");
}

Try / catch

try {
    PrivateKey key = PemReader.loadPrivateKeyFromPemFile(keyPath);
} catch (KeyManagementException e) {
    log.error("Cannot load TLS private key {}: {}", keyPath, e.getMessage());
    throw new RuntimeException("Check key format (PKCS8, unencrypted) and provider support", e);
}

Prevention

When it happens

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

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

Related errors


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