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 IESParameterSpec

View on GitHub (pinned to 820761864e)

Solutions

  1. Regenerate the key pair as RSA: openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem
  2. Or use EC on a named curve: openssl ecparam -name prime256v1 -genkey -noout -out private.pem
  3. Check the algorithm string with openssl pkey -pubin -in key.pem -text -noout and confirm it is RSA or EC
  4. 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

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


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