apache/pulsar · error · IllegalArgumentException

Must provide encryption key name for crypto key reader

Error message

Must provide encryption key name for crypto key reader

What it means

Pulsar Functions validate that, when producer-side encryption is configured, a CryptoKeyReader implementation class AND at least one encryption key name are both set. This error means cryptoConfig was provided with a cryptoKeyReaderClassName but the encryptionKeys array is null or empty, so the key reader would have no keys to supply to the broker. It is thrown by doCommonChecks during function validation.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java:943

                            "CryptoKeyReader class name required");
                }
                if (conf.getMessagePayloadProcessorConfig() != null && isBlank(
                        conf.getMessagePayloadProcessorConfig().getClassName())) {
                    throw new IllegalArgumentException(
                            "MessagePayloadProcessor class name required");
                }
            });
        }

        if (functionConfig.getProducerConfig() != null
                && functionConfig.getProducerConfig().getCryptoConfig() != null) {
            if (isBlank(functionConfig.getProducerConfig().getCryptoConfig().getCryptoKeyReaderClassName())) {
                throw new IllegalArgumentException("CryptoKeyReader class name required");
            }

            if (functionConfig.getProducerConfig().getCryptoConfig().getEncryptionKeys() == null
                    || functionConfig.getProducerConfig().getCryptoConfig().getEncryptionKeys().length == 0) {
                throw new IllegalArgumentException("Must provide encryption key name for crypto key reader");
            }
        }
    }

    public static Collection<String> collectAllInputTopics(FunctionConfig functionConfig) {
        List<String> retval = new LinkedList<>();
        if (functionConfig.getInputs() != null) {
            retval.addAll(functionConfig.getInputs());
        }
        if (functionConfig.getTopicsPattern() != null) {
            retval.add(functionConfig.getTopicsPattern());
        }
        if (functionConfig.getCustomSerdeInputs() != null) {
            retval.addAll(functionConfig.getCustomSerdeInputs().keySet());
        }
        if (functionConfig.getCustomSchemaInputs() != null) {
            retval.addAll(functionConfig.getCustomSchemaInputs().keySet());
        }

View on GitHub (pinned to 820761864e)

Solutions

  1. Add the encryption key names to producerConfig.cryptoConfig.encryptionKeys, e.g. setEncryptionKeys(new String[]{"my-app-key"}).
  2. If encryption is not intended, remove the cryptoConfig section entirely instead of keeping only the key reader class.
  3. If keys are supplied via a different mechanism, ensure the config deserialization actually populates encryptionKeys (check YAML/JSON field names).

Example fix

// before
producerConfig.cryptoConfig.cryptoKeyReaderClassName = "org.example.MyCryptoKeyReader";
// encryptionKeys missing
// after
producerConfig.cryptoConfig.cryptoKeyReaderClassName = "org.example.MyCryptoKeyReader";
producerConfig.cryptoConfig.encryptionKeys = new String[]{"my-app-key"};
Defensive patterns

Strategy: validation

Validate before calling

CryptoConfig cc = cfg.getProducerConfig().getCryptoConfig();
if (cc != null && cc.getCryptoKeyReaderClassName() != null
        && (cc.getEncryptionKeys() == null || cc.getEncryptionKeys().length == 0)) {
    throw new IllegalArgumentException("encryptionKeys must be set when cryptoKeyReaderClassName is set");
}

Type guard

boolean hasEncryptionKeys(FunctionConfig c) {
    return c.getProducerConfig() != null && c.getProducerConfig().getCryptoConfig() != null
        && c.getProducerConfig().getCryptoConfig().getEncryptionKeys() != null
        && c.getProducerConfig().getCryptoConfig().getEncryptionKeys().length > 0;
}

Try / catch

try {
    FunctionConfigUtils.validateJavaFunction(config, pkg);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("encryption key name")) {
        config.getProducerConfig().getCryptoConfig().setEncryptionKeys(new String[]{"my-app-key"});
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling function update/create APIs (via validateNonJavaFunction or validateJavaFunction) with a FunctionConfig whose producerConfig.cryptoConfig.cryptoKeyReaderClassName is set but producerConfig.cryptoConfig.encryptionKeys is null or an empty array.

Common situations: Developers enable end-to-end encryption by copying a config snippet that sets the key reader class but forget to list the encryption key names (e.g. my-app-key) under encryptionKeys; or keys are removed from a YAML/JSON config leaving an empty list while the reader class remains.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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