{"record":{"id":"a87c248f98cdac6d","repo":"apache/pulsar","slug":"failed-to-read-decryption-key-from-keyuri","errorCode":null,"errorMessage":"Failed to read decryption key from ${keyUri}","messagePattern":"Failed to read decryption key from (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client-tools/src/main/java/org/apache/pulsar/client/cli/AbstractCmdConsume.java","lineNumber":211,"sourceCode":"            }\n            res.put(f.name(), fieldValue);\n        }\n        return res;\n    }\n\n    /**\n     * Build a consumer-side decryption policy from a {@code file://} key URI, mirroring the v4\n     * {@code defaultCryptoKeyReader(uri)} semantics: the private key is loaded once and returned\n     * for any key name. (The producer's logical key name travels in the message metadata, so a\n     * name-keyed provider would not resolve it; the CLI's file-based flow has a single key.)\n     */\n    protected static ConsumerEncryptionPolicy buildFileDecryptionPolicy(\n            String keyUri, ConsumerCryptoFailureAction failureAction) {\n        final byte[] keyBytes;\n        try {\n            keyBytes = Files.readAllBytes(fileUriToPath(keyUri));\n        } catch (IOException e) {\n            throw new IllegalArgumentException(\"Failed to read decryption key from \" + keyUri, e);\n        }\n        PrivateKeyProvider provider = (keyName, metadata) ->\n                CompletableFuture.completedFuture(EncryptionKey.of(keyBytes));\n        return ConsumerEncryptionPolicy.builder()\n                .privateKeyProvider(provider)\n                .failureAction(failureAction)\n                .build();\n    }\n\n    @WebSocket\n    @CustomLog\n    public static class ConsumerSocket {\n        private static final String X_PULSAR_MESSAGE_ID = \"messageId\";\n        private final CountDownLatch closeLatch;\n        private Session session;\n        private CompletableFuture<Void> connected;\n        final BlockingQueue<String> incomingMessages;\n","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-tools/src/main/java/org/apache/pulsar/client/cli/AbstractCmdConsume.java#L193-L229","documentation":"buildFileDecryptionPolicy reads the decryption key file named by keyUri with Files.readAllBytes and wraps any IOException into an IllegalArgumentException. It means the file:// key location was valid as a URI but the bytes could not be read — typically the file is missing, unreadable, or a directory.","triggerScenarios":"Calling CmdConsume with a decryption key URI whose path does not exist, lacks read permission, is a directory, or whose device/path vanished (container mount not present, NFS down).","commonSituations":"Kubernetes/pod volume not mounted where the key was expected; typo in the key filename; file created by root but CLI runs as another user; relative path resolved against an unexpected working directory.","solutions":["Verify the resolved path exists and is a regular file (Files.isRegularFile) and is readable (Files.isReadable)","Fix the file:// URI (absolute path, correct host-empty form file:///path)","Check filesystem permissions/ownership for the user running pulsar-client, and that any volume mount is present","If the key is provisioned at startup, add a readiness check or wait loop before launching the consumer"],"exampleFix":"// before\n--decryption-key file:///etc/pulsar/decrytion-key.pem   // typo, file absent\n// after\nls -l /etc/pulsar/decryption-key.pem   # verify first\n--decryption-key file:///etc/pulsar/decryption-key.pem","handlingStrategy":"validation","validationCode":"Path p = fileUriToPath(keyUri);\nif (!Files.isRegularFile(p) || !Files.isReadable(p))\n    throw new IllegalArgumentException(\"Decryption key not readable: \" + p);","typeGuard":null,"tryCatchPattern":"try {\n    ConsumerEncryptionPolicy pol = buildFileDecryptionPolicy(keyUri, action);\n} catch (IllegalArgumentException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof NoSuchFileException) {\n        LOG.error(\"Key file missing: {}\", ((NoSuchFileException) cause).getFile());\n    } else if (cause instanceof AccessDeniedException) {\n        LOG.error(\"Key file not readable by current user\");\n    } else { throw e; }\n}","preventionTips":["Verify the key file exists and is readable as the same user running pulsar-client before launch","Use absolute paths in file:// URIs to avoid working-directory surprises","In containers/K8s, ensure secret volumes are mounted and add a readiness check on the key path","Check file permissions after provisioning scripts that create the key as root"],"tags":["io","filesystem","encryption","cli"],"backgroundTag":"file-not-found","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"}