apache/pulsar · error · PEMException

Unable to find EC Parameter for the given curve oid: ${ecOID

Error message

Unable to find EC Parameter for the given curve oid: ${ecOID.getId()}

What it means

During PEM public-key parsing in MessageCryptoBc.loadPublicKey, an ASN1ObjectIdentifier representing an EC curve OID was read from the PEM file, but BouncyCastle's ECNamedCurveTable.getByOID could not resolve it to a known curve's X9ECParameters. The library only supports named curves registered with BouncyCastle, so it throws PEMException rather than continuing with an unknown curve. This means the key file references an EC curve the bundled BC provider does not know by that OID.

Source

Thrown at pulsar-client-messagecrypto-bc/src/main/java/org/apache/pulsar/client/impl/crypto/MessageCryptoBc.java:275

    }

    public static PublicKey loadPublicKey(byte[] keyBytes) throws Exception {
        Reader keyReader = new StringReader(new String(keyBytes));
        PublicKey publicKey;
        try (PEMParser pemReader = new PEMParser(keyReader)) {
            Object pemObj = pemReader.readObject();
            JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter().setProvider(bcProvider());
            SubjectPublicKeyInfo keyInfo;
            X9ECParameters ecParam = null;

            if (pemObj instanceof ASN1ObjectIdentifier) {
                // make sure this is EC Parameter we're handling. In which case
                // we'll store it and read the next object which should be our
                // EC Public Key
                ASN1ObjectIdentifier ecOID = (ASN1ObjectIdentifier) pemObj;
                ecParam = ECNamedCurveTable.getByOID(ecOID);
                if (ecParam == null) {
                    throw new PEMException("Unable to find EC Parameter for the given curve oid: " + ecOID.getId());
                }
                pemObj = pemReader.readObject();
            } else if (pemObj instanceof X9ECParameters) {
                ecParam = (X9ECParameters) pemObj;
                pemObj = pemReader.readObject();
            }

            if (pemObj instanceof X509CertificateHolder) {
                keyInfo = ((X509CertificateHolder) pemObj).getSubjectPublicKeyInfo();
            } else {
                keyInfo = (SubjectPublicKeyInfo) pemObj;
            }
            publicKey = pemConverter.getPublicKey(keyInfo);

            if (ecParam != null && ECDSA.equals(publicKey.getAlgorithm())) {
                ECParameterSpec ecSpec = new ECParameterSpec(ecParam.getCurve(), ecParam.getG(), ecParam.getN(),
                        ecParam.getH(), ecParam.getSeed());
                KeyFactory keyFactory = KeyFactory.getInstance(ECDSA, bcProvider());

View on GitHub (pinned to 820761864e)

Solutions

  1. Regenerate the key pair with a standard named curve supported by BouncyCastle, e.g. prime256v1 (P-256) or secp384r1: openssl ecparam -name prime256v1 -genkey -noout -out private.pem
  2. Verify the curve OID in the PEM file: openssl asn1parse -in key.pem and confirm it maps to a named curve BC knows
  3. Upgrade/realign the BouncyCastle dependency so ECNamedCurveTable contains the curve referenced by the key
  4. Confirm the key file actually contains an EC public key and was not truncated or corrupted during distribution

Example fix

// before: key generated with unsupported curve
openssl ecparam -name secp256k1 -genkey -noout -out mykey.pem
// after: use a BC-supported named curve
openssl ecparam -name prime256v1 -genkey -noout -out mykey.pem
Defensive patterns

Strategy: validation

Validate before calling

// Check the PEM's curve is a BC named curve before calling addPublicKeyCipher
ASN1ObjectIdentifier oid = /* parse from PEM */;
if (org.bouncycastle.asn1.ec.ECNamedCurveTable.getByOID(oid) == null) {
    throw new IllegalArgumentException("Unsupported EC curve OID: " + oid.getId() +
        "; regenerate key with prime256v1 or secp384r1");
}

Try / catch

try {
    crypto.addPublicKeyCipher(keyName, keyReader);
} catch (PulsarClientException.CryptoException | org.bouncycastle.openssl.PEMException e) {
    log.error("EC key rejected (unsupported curve?): {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling addPublicKeyCipher(keyName, keyReader) where keyReader.getPublicKey returns key bytes whose PEM EC public key header contains an ECParameters OID that ECNamedCurveTable does not resolve (unrecognized curve OID, e.g. a curve absent from the BC version in use, or a malformed/typo'd OID).

Common situations: Producers with ECDSA encryption keys generated with an unusual or exotic curve (e.g. secp256k1 or a custom curve not in BC's named table for the bundled BC version); key files edited or regenerated after a BouncyCastle version change; copying an OID string incorrectly into a hand-written key file.

Related errors


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