apache/pulsar · error · RuntimeException

failed to get client token

Error message

failed to get client token

What it means

TokenAuthenticationV5.token() fetches the token through a pluggable Supplier. Any Throwable thrown by the supplier (file read failure, parse error, static token code path failure) is caught and rethrown as a RuntimeException "failed to get client token" with the original cause attached.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/auth/v5/TokenAuthenticationV5.java:189

    @Override
    public CompletableFuture<HttpAuthHeaders> getHttpHeadersAsync(HttpAuthCallContext ctx) {
        return V5AuthContexts.supplyBlocking(blockingExecutor, () -> {
            Map<String, String> headers = new LinkedHashMap<>();
            headers.put(PULSAR_AUTH_METHOD_NAME, AUTH_METHOD_NAME);
            headers.put(HTTP_HEADER_NAME, "Bearer " + token());
            return HttpAuthHeaders.of(headers);
        });
    }

    @Override
    public void close() {
    }

    private String token() {
        try {
            return tokenSupplier.get();
        } catch (Throwable t) {
            throw new RuntimeException("failed to get client token", t);
        }
    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. Inspect the wrapped cause (getCause()) to find the real failure and fix it (file path, network, credentials).
  2. If using a file token, see the token file path/permissions fix; if using a custom supplier, harden it or add retry/caching logic.
  3. Verify the token value itself is valid at configuration time (present, non-empty) so the supplier never throws for trivial reasons.

Example fix

// before
Supplier<String> s = () -> vaultClient.fetch(); // throws on outage
// after
Supplier<String> s = () -> {
    try { return vaultClient.fetch(); }
    catch (Exception e) { return cachedToken.orElseThrow(() -> e); }
};
Defensive patterns

Strategy: try-catch

Validate before calling

// dry-run the supplier before client startup
String probe;
try { probe = tokenSupplier.get(); } catch (Throwable t) {
    throw new IllegalStateException("token supplier failed at startup", t);
}
if (probe == null || probe.isEmpty()) throw new IllegalStateException("empty client token");

Try / catch

try {
    String t = authenticationToken();
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().equals("failed to get client token")) {
        Throwable cause = e.getCause(); // inspect and remediate the real failure
    } else throw e;
}

Prevention

When it happens

Trigger: Calling the token() accessor when the configured tokenSupplier throws — e.g. the file-backed supplier hitting an IOException (see token-file error), or a custom supplier failing to fetch/refresh the token.

Common situations: Expired/rotated credential files disappearing at fetch time; custom token suppliers making network calls to a vault that is down; supplying a supplier that throws on first use because configuration was invalid.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/50ddaf5022107fda. Report an issue: GitHub.