{"record":{"id":"40d8058ed2f9b7f3","repo":"apache/pulsar","slug":"keyname-or-keyreader-is-null","errorCode":null,"errorMessage":"Keyname or KeyReader is null","messagePattern":"Keyname or KeyReader is null","errorType":"validation","errorClass":"PulsarClientException.CryptoException","httpStatus":null,"severity":"error","filePath":"pulsar-client-messagecrypto-bc/src/main/java/org/apache/pulsar/client/impl/crypto/MessageCryptoBc.java","lineNumber":373,"sourceCode":"     *\n     * @param keyNames List of public keys to encrypt data key\n     *\n     * @param keyReader Implementation to read the key values\n     *\n     */\n    @Override\n    public void addPublicKeyCipher(Set<String> keyNames, CryptoKeyReader keyReader) throws CryptoException {\n        // Rotate the encryption key each time this method is called\n        encryptionKey = generateEncryptionKey();\n\n        for (String key : keyNames) {\n            addPublicKeyCipher(key, keyReader);\n        }\n    }\n\n    private void addPublicKeyCipher(String keyName, CryptoKeyReader keyReader) throws CryptoException {\n        if (keyName == null || keyReader == null) {\n            throw new PulsarClientException.CryptoException(\"Keyname or KeyReader is null\");\n        }\n\n        // Read the public key and its info using callback\n        EncryptionKeyInfo keyInfo = keyReader.getPublicKey(keyName, null);\n\n        PublicKey pubKey;\n\n        try {\n            pubKey = loadPublicKey(keyInfo.getKey());\n        } catch (Exception e) {\n            String msg = logCtx + \"Failed to load public key \" + keyName + \". \" + e.getMessage();\n            log.error(msg);\n            throw new PulsarClientException.CryptoException(msg);\n        }\n\n        Cipher dataKeyCipher;\n        byte[] encryptedKey;\n        try {","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-messagecrypto-bc/src/main/java/org/apache/pulsar/client/impl/crypto/MessageCryptoBc.java#L355-L391","documentation":"MessageCryptoBc.addPublicKeyCipher validates its arguments before doing any crypto work: if either the key name or the CryptoKeyReader is null it cannot obtain the encryption key, so it throws PulsarClientException.CryptoException immediately. This is a fail-fast argument check, not a crypto failure.","triggerScenarios":"Calling producer/reader addEncryptionKey(keyName) (which delegates to addPublicKeyCipher) with a null keyName, or when no CryptoKeyReader has been configured on the client builder so keyReader is null.","commonSituations":"Forgetting to call .addKeyReader(keyReader) (or the older cryptoKeyReader config) on the ProducerBuilder while enabling end-to-end encryption; a typo in the key name variable that leaves it uninitialized; building configuration programmatically where a required property failed to load and stayed null.","solutions":["Configure a CryptoKeyReader on the builder: .addKeyReader(new DefaultCryptoKeyReader(keyReaderFilePath))","Pass a non-null key name to addEncryptionKey() and verify it matches a key your reader can serve via getPublicKey","Validate configuration loading so keyName/keyReaderPath values are actually populated before building the producer","Null-check these values in your own startup code to fail with a clearer message"],"exampleFix":"// before\nProducer<byte[]> p = client.newProducer().addEncryptionKey(\"myapp.key\").create(); // no key reader\n// after\nCryptoKeyReader reader = new DefaultCryptoKeyReader(\"/path/to/public/key.pem\");\nProducer<byte[]> p = client.newProducer().addKeyReader(reader).addEncryptionKey(\"myapp.key\").create();","handlingStrategy":"validation","validationCode":"if (keyName == null || keyName.isEmpty()) {\n    throw new IllegalArgumentException(\"encryption key name must be set\");\n}\nif (keyReader == null) {\n    throw new IllegalArgumentException(\"CryptoKeyReader must be configured before enabling encryption\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    producer = client.newProducer().addKeyReader(keyReader).addEncryptionKey(keyName).create();\n} catch (PulsarClientException.CryptoException e) {\n    log.error(\"Encryption config incomplete: {}\", e.getMessage());\n}","preventionTips":["Always call addKeyReader() on the builder whenever addEncryptionKey() is used","Load key names and reader paths from validated configuration with startup-time null checks","Fail fast in application bootstrap rather than lazily at publish time","Keep key names in one constants/config class to avoid uninitialized variables"],"tags":["configuration","null-check","encryption","crypto-key-reader"],"backgroundTag":"missing-required-config","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}