apache/pulsar · error · PulsarClientException.CryptoException
${logCtx}Failed to load public key ${keyName}. ${e.getMessag
Error message
${logCtx}Failed to load public key ${keyName}. ${e.getMessage()} What it means
This is a wrapping error: addPublicKeyCipher loaded the key bytes from the CryptoKeyReader and passed them to loadPublicKey, which failed (bad PEM format, unsupported curve, non-EC/RSA content, parse error). The code logs and rethrows the failure as a CryptoException prefixed with 'Failed to load public key <keyName>', embedding the underlying exception message.
Source
Thrown at pulsar-client-messagecrypto-bc/src/main/java/org/apache/pulsar/client/impl/crypto/MessageCryptoBc.java:386
}
}
private void addPublicKeyCipher(String keyName, CryptoKeyReader keyReader) throws CryptoException {
if (keyName == null || keyReader == null) {
throw new PulsarClientException.CryptoException("Keyname or KeyReader is null");
}
// Read the public key and its info using callback
EncryptionKeyInfo keyInfo = keyReader.getPublicKey(keyName, null);
PublicKey pubKey;
try {
pubKey = loadPublicKey(keyInfo.getKey());
} catch (Exception e) {
String msg = logCtx + "Failed to load public key " + keyName + ". " + e.getMessage();
log.error(msg);
throw new PulsarClientException.CryptoException(msg);
}
Cipher dataKeyCipher;
byte[] encryptedKey;
try {
AlgorithmParameterSpec params = null;
// Encrypt data key using public key
if (RSA.equals(pubKey.getAlgorithm())) {
dataKeyCipher = Cipher.getInstance(RSA_TRANS, bcProvider());
} else if (ECDSA.equals(pubKey.getAlgorithm())) {
dataKeyCipher = Cipher.getInstance(ECIES, bcProvider());
params = createIESParameterSpec();
} else {
String msg = logCtx + "Unsupported key type " + pubKey.getAlgorithm() + " for key " + keyName;
log.error(msg);
throw new PulsarClientException.CryptoException(msg);
}
if (params != null) {View on GitHub (pinned to 820761864e)
Solutions
- Read the embedded cause message in the exception and fix the underlying parse failure it reports
- Verify the key file contains a valid PEM block starting with '-----BEGIN PUBLIC KEY-----' (or EC PARAMETERS followed by EC PUBLIC KEY)
- Confirm the keyName passed to addEncryptionKey exactly matches the key file name the CryptoKeyReader resolves
- Test parsing locally: openssl pkey -pubin -in key.pem -text -noout to confirm the key is loadable and of a supported type (RSA or EC on a named curve)
Example fix
// before: certificate passed where a public key is expected
CryptoKeyReader reader = new DefaultCryptoKeyReader("/certs/server.crt");
// after: extract the public key PEM
// openssl x509 -in server.crt -pubkey -noout > public.key
CryptoKeyReader reader = new DefaultCryptoKeyReader("/certs/public.key"); Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate the key material served by the reader
byte[] keyBytes = keyReader.getPublicKey(keyName, null).getKey();
String pem = new String(keyBytes, StandardCharsets.UTF_8);
if (!pem.contains("BEGIN PUBLIC KEY") && !pem.contains("BEGIN EC PUBLIC KEY")) {
throw new IllegalStateException(keyName + " does not contain a public key PEM block");
} Try / catch
try {
crypto.addPublicKeyCipher(keyName, keyReader);
} catch (PulsarClientException.CryptoException e) {
// message embeds the underlying load failure; surface it with key context
throw new IllegalStateException("Public key '" + keyName + "' failed to load: " + e.getMessage(), e);
} Prevention
- Ensure key file names on disk exactly match the names passed to addEncryptionKey
- Distribute PEM public keys (not certificates or private keys) to the KeyReader path
- Verify keys after secret-manager injection; some tooling mangles newlines/encoding
- Smoke-test key parsing at service startup
When it happens
Trigger: addPublicKeyCipher is invoked with a keyName whose keyReader.getPublicKey(keyName, null) returns bytes that loadPublicKey cannot parse: invalid PEM, DER structure errors, unsupported EC curve OID (see the PEMException cases), or a key format not matching RSA/EC expectations.
Common situations: Key name passed to addEncryptionKey does not match a key file in the CryptoKeyReader directory; the public key file contains a private key or certificate instead of a PUBLIC KEY PEM block; key file corrupted in transit; unsupported curve; whitespace/encoding mangling from secret-management tooling.
Related errors
- Unable to find EC Parameter for the given curve oid: ${ecOID
- Failed to decode private key
- Failed to decode public key
- privateKeyProvider must be set when failureAction is FAIL
- ${logCtx}Unsupported key type ${pubKey.getAlgorithm()} for k
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/7bcca82bb070d5ba.
Report an issue: GitHub.