apache/pulsar · error · IllegalArgumentException

Missing encryption key name for producer crypto key reader

Error message

Missing encryption key name for producer crypto key reader

What it means

When a crypto key reader is configured on the producer side (isProducer == true), encryptionKeys must list at least one public key name used to encrypt the message. validateCryptoKeyReader throws this IllegalArgumentException when getEncryptionKeys() is null or empty.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/ValidatorUtils.java:99

                    String.format("The crypto key reader class %s does not exist", cryptoClassName));
        }
        if (!cryptoClass.asErasure().isAssignableTo(CryptoKeyReader.class)) {
            throw new IllegalArgumentException(
                    String.format("%s does not implement %s", cryptoClassName, CryptoKeyReader.class.getName()));
        }

        boolean hasConstructor = cryptoClass.getDeclaredMethods().stream()
                .anyMatch(method -> method.isConstructor() && method.getParameters().size() == 1
                        && method.getParameters().get(0).getType().asErasure().represents(Map.class));

        if (!hasConstructor) {
            throw new IllegalArgumentException(
                    String.format("The crypto key reader class %s does not implement the desired constructor.",
                            conf.getCryptoKeyReaderClassName()));
        }

        if (isProducer && (conf.getEncryptionKeys() == null || conf.getEncryptionKeys().length == 0)) {
            throw new IllegalArgumentException("Missing encryption key name for producer crypto key reader");
        }
    }

    public static void validateMessagePayloadProcessor(MessagePayloadProcessorConfig conf, TypePool typePool) {
        if (isEmpty(conf.getClassName())) {
            return;
        }

        String payloadProcessorClassName = conf.getClassName();
        TypeDescription payloadProcessorClass = null;
        try {
            payloadProcessorClass = typePool.describe(payloadProcessorClassName).resolve();
        } catch (TypePool.Resolution.NoSuchTypeException e) {
            throw new IllegalArgumentException(
                    String.format("The message payload processor class %s does not exist", payloadProcessorClassName));
        }
        if (!payloadProcessorClass.asErasure().isAssignableTo(MessagePayloadProcessor.class)) {
            throw new IllegalArgumentException(String.format("%s does not implement %s", payloadProcessorClassName,

View on GitHub (pinned to 820761864e)

Solutions

  1. Set encryptionKeys in the producer conf (or pass --encryption-key) with the key names available from the key reader
  2. If encryption is not intended, remove the cryptoKeyReaderClassName instead of leaving crypto half-configured

Example fix

// before
// producerConf: { "cryptoKeyReaderClassName": "com.acme.MyKeyReader" } // no encryptionKeys
// after
// producerConf: { "cryptoKeyReaderClassName": "com.acme.MyKeyReader", "encryptionKeys": ["my-public-key"] }
Defensive patterns

Strategy: validation

Validate before calling

if (isProducer && (conf.getEncryptionKeys() == null || conf.getEncryptionKeys().length == 0)) {
    throw new IllegalStateException("Producer crypto requires encryptionKeys to be set");
}

Try / catch

try {
    ValidatorUtils.validateCryptoKeyReader(conf, typePool, true);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Missing encryption key name")) {
        // set encryptionKeys in producer conf or drop the crypto config
    }
    throw e;
}

Prevention

When it happens

Trigger: Setting cryptoKeyReaderClassName in a source function's producer conf without setting encryptionKeys, or setting encryptionKeys to an empty array, while isProducer is true.

Common situations: Copying a consumer-side crypto config into a source function; forgetting the --encryption-key CLI flag; clearing encryption keys after switching to encrypted topics.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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