{"record":{"id":"011351682d0b85be","repo":"apache/pulsar","slug":"failed-to-get-client-token","errorCode":null,"errorMessage":"failed to get client token","messagePattern":"failed to get client token","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationDataToken.java","lineNumber":64,"sourceCode":"    public Set<Map.Entry<String, String>> getHttpHeaders() {\n        return this.headers.entrySet();\n    }\n\n    @Override\n    public boolean hasDataFromCommand() {\n        return true;\n    }\n\n    @Override\n    public String getCommandData() {\n        return getToken();\n    }\n\n    private String getToken() {\n        try {\n            return tokenSupplier.get();\n        } catch (Throwable t) {\n            throw new RuntimeException(\"failed to get client token\", t);\n        }\n    }\n}\n","sourceCodeStart":46,"sourceCodeEnd":68,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationDataToken.java#L46-L68","documentation":"AuthenticationDataToken.getToken() invokes its tokenSupplier and wraps any Throwable in RuntimeException(\"failed to get client token\", t). getToken backs getCommandData(), so every protocol command that needs the bearer token re-evaluates the supplier; any failure inside it (file read, secret lookup, NPE on a null supplier result) surfaces as this runtime exception.","triggerScenarios":"The Supplier<String> passed to AuthenticationToken/AuthenticationDataToken throws: token file missing or unreadable, secret-manager lookup fails, supplier returns null and downstream code NPEs, or a static token string configured as invalid/blank causing parsing failure.","commonSituations":"Kubernetes secret rotated/deleted while the client is running; token file path from env var not set; vault/DynamicTokenSupplier outage; using AuthenticationToken with a function that returns null after expiry handling; authParams JSON missing the 'token' key so the supplier resolves to nothing.","solutions":["Inspect the wrapped cause (getCause()) to find why the supplier failed (missing file, null token, secret lookup error).","Ensure the token source is available and returns a valid non-blank JWT before/while the client runs.","For file-based tokens, verify the token file path exists and is readable at runtime, not just at startup.","Harden custom token suppliers to throw descriptive exceptions and never return null."],"exampleFix":"// before\nSupplier<String> supplier = () -> Files.exists(path) ? readToken(path) : null; // null -> NPE wrapped as this error\n// after\nSupplier<String> supplier = () -> {\n    if (!Files.isReadable(path)) throw new IllegalStateException(\"token file missing: \" + path);\n    return readToken(path);\n};","handlingStrategy":"try-catch","validationCode":"Supplier<String> safeSupplier = () -> {\n    String t = rawSupplier.get();\n    if (t == null || t.isBlank()) throw new IllegalStateException(\"token supplier produced a blank token\");\n    return t;\n};","typeGuard":"boolean isUsableToken(String t) { return t != null && t.split(\"\\\\.\").length == 3; } // compact JWT","tryCatchPattern":"try {\n    client = PulsarClient.builder().authentication(AuthenticationFactory.token(supplier))...create();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"failed to get client token\")) {\n        log.error(\"token supplier failed: {}\", e.getCause(), e);\n    }\n    throw e;\n}","preventionTips":["Wrap custom token suppliers to validate the token is non-null and looks like a JWT.","Monitor/refresh token files and secrets so they remain readable while the client runs.","Log e.getCause() to identify the real supplier failure (missing file, secret outage).","Pre-authenticate once at startup so supplier failures surface before traffic."],"tags":["java","authentication","jwt","token","pulsar-client"],"backgroundTag":"missing-auth-token","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"}