apache/pulsar · error · PulsarClientException.CryptoException
${logCtx}Unsupported key type ${pubKey.getAlgorithm()} for k
Error message
${logCtx}Unsupported key type ${pubKey.getAlgorithm()} for key ${keyName} What it means
After successfully loading the key, addPublicKeyCipher selects a cipher by the key's algorithm: RSA and ECDSA are supported (RSA/ECB/OAEPWithSHA-1AndMGF1Padding and ECIES respectively). If pubKey.getAlgorithm() is anything else (e.g. DSA, Ed25519, or an unrecognized string), the library cannot encrypt the data key and throws CryptoException naming the unsupported algorithm and key.
Source
Thrown at pulsar-client-messagecrypto-bc/src/main/java/org/apache/pulsar/client/impl/crypto/MessageCryptoBc.java:402
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) {
dataKeyCipher.init(Cipher.ENCRYPT_MODE, pubKey, params);
} else {
dataKeyCipher.init(Cipher.ENCRYPT_MODE, pubKey);
}
encryptedKey = dataKeyCipher.doFinal(encryptionKey.getEncoded());
} catch (IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException
| NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
log.error().attr("logCtx", logCtx).attr("keyName", keyName)
.exceptionMessage(e).log("Failed to encrypt data key");
throw new PulsarClientException.CryptoException(e.getMessage());
}
EncryptionKeyInfo eki = new EncryptionKeyInfo(encryptedKey, keyInfo.getMetadata());
encryptedDataKeyMap.put(keyName, eki);
}
// required since Bouncycastle 1.72 when using ECIES, it is required to pass in an IESParameterSpecView on GitHub (pinned to 820761864e)
Solutions
- Regenerate the key pair as RSA: openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem
- Or use EC on a named curve: openssl ecparam -name prime256v1 -genkey -noout -out private.pem
- Check the algorithm string with openssl pkey -pubin -in key.pem -text -noout and confirm it is RSA or EC
- If using a custom KeyReader, ensure the key bytes decode to a standard RSA/EC PublicKey
Example fix
// before: ed25519 key unsupported by Pulsar E2E encryption ssh-keygen or openssl genpkey -algorithm ED25519 ... // after: use RSA openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the key algorithm is supported before enabling encryption
PublicKey pubKey = KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(keyInfo.getKey())); // or EC
String alg = pubKey.getAlgorithm();
if (!alg.equals("RSA") && !alg.equals("EC")) {
throw new IllegalStateException("Unsupported key algorithm for Pulsar E2E encryption: " + alg);
} Try / catch
try {
crypto.addPublicKeyCipher(keyName, keyReader);
} catch (PulsarClientException.CryptoException e) {
if (e.getMessage().contains("Unsupported key type")) {
throw new IllegalStateException("Regenerate " + keyName + " as RSA or EC key", e);
}
throw e;
} Prevention
- Standardize on RSA-2048 or EC prime256v1 keys for Pulsar end-to-end encryption
- Do not use Ed25519/DSA keys — Pulsar's MessageCryptoBc supports only RSA and ECDSA
- Print the algorithm (openssl pkey -pubin -text -noout) when provisioning new keys
- Document key-generation commands in your ops runbook to prevent tooling defaults like Ed25519
When it happens
Trigger: Calling addEncryptionKey with a key whose parsed algorithm is neither 'RSA' nor 'EC' (ECDSA) — for example a DSA public key, an EdDSA/Ed25519 key, or a provider returning a non-standard algorithm string.
Common situations: Generating keys with modern tooling that defaults to Ed25519; using DSA keys from legacy setups; providing a key type Pulsar's end-to-end encryption does not support (it supports RSA and ECDSA only); keys produced by a provider whose getAlgorithm() returns a custom alias.
Related errors
- privateKeyProvider must be set when failureAction is FAIL
- ${logCtx}Failed to load public key ${keyName}. ${e.getMessag
- getPublicKey called on a consumer-side CryptoKeyReaderAdapte
- getPrivateKey called on a producer-side CryptoKeyReaderAdapt
- Must provide encryption key name for crypto key reader
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/f25e4ce9a0e039ed.
Report an issue: GitHub.