{"record":{"id":"3da0edb87058cdc6","repo":"apache/pulsar","slug":"failed-to-read-token-from-file","errorCode":null,"errorMessage":"Failed to read token from file","messagePattern":"Failed to read token from file","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/v5/TokenAuthenticationV5.java","lineNumber":135,"sourceCode":"        }\n    }\n\n    /** A supplier reading the token from a file on every call, so a rotated token is picked up. */\n    public static final class FileTokenSupplier implements Supplier<String>, Serializable {\n\n        private static final long serialVersionUID = 3160666668166028760L;\n        private final URI uri;\n\n        public FileTokenSupplier(final URI uri) {\n            this.uri = uri;\n        }\n\n        @Override\n        public String get() {\n            try {\n                return new String(Files.readAllBytes(Paths.get(uri)), StandardCharsets.UTF_8).trim();\n            } catch (IOException e) {\n                throw new RuntimeException(\"Failed to read token from file\", e);\n            }\n        }\n    }\n\n    private final Supplier<String> tokenSupplier;\n\n    // Late-bound at initializeAsync(...): the client's bounded blocking executor, onto which the token()\n    // read is off-loaded so a file-backed supplier (Files.readAllBytes) never runs on the Netty event loop\n    // (PIP-478). Null when used outside a client, in which case the read runs inline.\n    private transient volatile Executor blockingExecutor;\n\n    /**\n     * @param tokenSupplier supplies the current token on each call (enables refresh without rebuild)\n     */\n    public TokenAuthenticationV5(Supplier<String> tokenSupplier) {\n        this.tokenSupplier = tokenSupplier;\n    }\n","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/v5/TokenAuthenticationV5.java#L117-L153","documentation":"TokenAuthenticationV5 supports reading the client token from a file:// URI. The file-backed token supplier reads all bytes of the file on each get(); an IOException (missing file, permissions, directory instead of file) is rethrown as a RuntimeException with this message, wrapping the original IOException.","triggerScenarios":"Configuring authentication with tokenFromFile / a file: URI where the path does not exist, is not readable, or is a directory; the token file being deleted or rotated out from under a running client that calls get() lazily.","commonSituations":"Kubernetes secret mounts not yet projected at client startup; wrong path in authParams (typos, container vs host paths); file permissions changed after deployment; token file removed by a secret rotation job.","solutions":["Verify the token file path exists and is readable by the process user before starting the client (ls/permissions).","Fix the URI in the auth configuration (token file parameter) to the correct absolute path.","In Kubernetes, confirm the projected volume/secret is mounted and populated before the client starts; add an initContainer wait if needed.","If tokens rotate by replacement, ensure the path always resolves (symlink swap, not delete+create)."],"exampleFix":"// before\nAuthParams: token:file:///etc/pulsar/token          (file missing)\n// after\nAuthParams: token:file:///var/run/secrets/pulsar/token  (verified mounted & readable)","handlingStrategy":"try-catch","validationCode":"java.nio.file.Path p = java.nio.file.Path.of(uri.getPath());\nif (!java.nio.file.Files.isRegularFile(p) || !java.nio.file.Files.isReadable(p)) {\n    throw new IllegalStateException(\"token file missing or unreadable: \" + p);\n}","typeGuard":null,"tryCatchPattern":"try {\n    String token = tokenSupplier.get();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().equals(\"Failed to read token from file\")) {\n        // check path/mount/permissions, then re-init auth\n    } else throw e;\n}","preventionTips":["Validate the token file exists and is readable at startup, before creating the client.","In Kubernetes, gate client startup on the projected secret being present (initContainer or readiness check).","Rotate token files atomically (symlink swap) so a reader never sees a missing path."],"tags":["token-auth","file-io","ioexception","configuration"],"backgroundTag":"token-file-unreadable","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"}