{"record":{"id":"ce849260d5c7533d","repo":"apache/pulsar","slug":"at-least-one-key-name-must-be-configured","errorCode":null,"errorMessage":"at least one key name must be configured","messagePattern":"at least one key name must be configured","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/ProducerEncryptionPolicy.java","lineNumber":48,"sourceCode":" *\n * <p>Construct via {@link #builder()}. Required: a {@link PublicKeyProvider} and at\n * least one key name.\n */\n@EqualsAndHashCode\n@ToString\npublic final class ProducerEncryptionPolicy {\n\n    private final PublicKeyProvider publicKeyProvider;\n    private final List<String> keyNames;\n    private final ProducerCryptoFailureAction failureAction;\n\n    private ProducerEncryptionPolicy(PublicKeyProvider publicKeyProvider,\n                                     List<String> keyNames,\n                                     ProducerCryptoFailureAction failureAction) {\n        Objects.requireNonNull(publicKeyProvider, \"publicKeyProvider must not be null\");\n        Objects.requireNonNull(keyNames, \"keyNames must not be null\");\n        if (keyNames.isEmpty()) {\n            throw new IllegalArgumentException(\"at least one key name must be configured\");\n        }\n        Objects.requireNonNull(failureAction, \"failureAction must not be null\");\n        this.publicKeyProvider = publicKeyProvider;\n        this.keyNames = List.copyOf(keyNames);\n        this.failureAction = failureAction;\n    }\n\n    /**\n     * @return the provider used to load public keys for encryption\n     */\n    public PublicKeyProvider publicKeyProvider() {\n        return publicKeyProvider;\n    }\n\n    /**\n     * @return the configured key names; the producer encrypts each message's data\n     *         key with every public key listed here\n     */","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-api-v5/src/main/java/org/apache/pulsar/client/api/v5/config/ProducerEncryptionPolicy.java#L30-L66","documentation":"ProducerEncryptionPolicy requires at least one encryption key name. The producer-side encryption policy wraps messages with one of the configured public keys, so an empty keyNames list makes encryption impossible; the constructor validates this and throws IllegalArgumentException after checking keyNames is non-null.","triggerScenarios":"Calling ProducerEncryptionPolicy.builder().build() (or the private constructor) with keyNames never set, set to List.of() / Collections.emptyList(), or an explicitly empty list passed to the builder.","commonSituations":"Reading key names from config where the encryption.keys property is empty or missing; programmatically building the list from a filtered collection that ended up empty.","solutions":["Add at least one key: .addKeyName(\"my-encryption-key\") (or .keyNames(List.of(\"key1\"))) on the builder before build()","Verify the broker cluster actually has the corresponding public key loaded via the admin API","Check the config source supplying the key names and fail earlier with a clearer message if it is empty"],"exampleFix":"// before\nProducerEncryptionPolicy p = ProducerEncryptionPolicy.builder()\n        .publicKeyProvider(provider)\n        .failureAction(ProducerCryptoFailureAction.FAIL)\n        .build();\n// after\nProducerEncryptionPolicy p = ProducerEncryptionPolicy.builder()\n        .publicKeyProvider(provider)\n        .addKeyName(\"my-encryption-key\")\n        .failureAction(ProducerCryptoFailureAction.FAIL)\n        .build();","handlingStrategy":"validation","validationCode":"List<String> keyNames = config.getEncryptionKeyNames();\nif (keyNames == null || keyNames.isEmpty()) {\n    throw new IllegalArgumentException(\"producerEncryptionPolicy requires at least one encryption key name\");\n}","typeGuard":"boolean hasKeyNames(List<String> l) { return l != null && !l.isEmpty(); }","tryCatchPattern":"try {\n    policy = ProducerEncryptionPolicy.builder()...build();\n} catch (IllegalArgumentException e) {\n    log.error(\"Producer encryption policy invalid: {}\", e.getMessage());\n    throw new IllegalStateException(\"Fix encryption key configuration\", e);\n}","preventionTips":["Keep encryption key names in a required config field with startup-time checks","Verify broker has the corresponding public key configured","Fail fast at application startup if key names list is empty"],"tags":["java","validation","encryption","client-config"],"backgroundTag":"empty-list-validation","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}