apache/pulsar · critical · IOException
No secret key was provided for token authentication
Error message
No secret key was provided for token authentication
What it means
During provider initialization, getValidationKey looks for a token validation key in the configuration: first tokenSecretKey (symmetric), then tokenPublicKey (asymmetric). If neither property is set (blank), it throws this IOException because the provider has no key with which to verify token signatures.
Source
Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderToken.java:300
Optional<String> firstEntry = list.stream().findFirst().map(Object::toString);
return firstEntry.orElse(null);
}
}
/**
* Try to get the validation key for tokens from several possible config options.
*/
private Key getValidationKey(ServiceConfiguration conf) throws IOException {
String tokenSecretKey = (String) conf.getProperty(confTokenSecretKeySettingName);
String tokenPublicKey = (String) conf.getProperty(confTokenPublicKeySettingName);
if (StringUtils.isNotBlank(tokenSecretKey)) {
final byte[] validationKey = AuthTokenUtils.readKeyFromUrl(tokenSecretKey);
return AuthTokenUtils.decodeSecretKey(validationKey);
} else if (StringUtils.isNotBlank(tokenPublicKey)) {
final byte[] validationKey = AuthTokenUtils.readKeyFromUrl(tokenPublicKey);
return AuthTokenUtils.decodePublicKey(validationKey, publicKeyAlg);
} else {
throw new IOException("No secret key was provided for token authentication");
}
}
private String getTokenRoleClaim(ServiceConfiguration conf) throws IOException {
String tokenAuthClaim = (String) conf.getProperty(confTokenAuthClaimSettingName);
if (StringUtils.isNotBlank(tokenAuthClaim)) {
return tokenAuthClaim;
} else {
return Claims.SUBJECT;
}
}
private SignatureAlgorithm getPublicKeyAlgType(ServiceConfiguration conf) throws IllegalArgumentException {
String tokenPublicAlg = (String) conf.getProperty(confTokenPublicAlgSettingName);
if (StringUtils.isNotBlank(tokenPublicAlg)) {
try {
return SignatureAlgorithm.forName(tokenPublicAlg);
} catch (SignatureException ex) {View on GitHub (pinned to 820761864e)
Solutions
- Set tokenSecretKey in broker.conf/standalone.conf to the base64-encoded secret key (or data: URL) used to sign tokens, e.g. tokenSecretKey=data:;base64,<key>.
- For asymmetric setups, set tokenPublicKey (and tokenPublicKeyAlg for non-RS256 algorithms) instead.
- Verify the property names are spelled correctly and the values are non-blank after config loading.
- Generate a key if none exists: bin/pulsar tokens create-secret-key --output my-secret.key --base64.
Example fix
// before (broker.conf) # tokenSecretKey= // after tokenSecretKey=data:;base64,base64EncodedSecretKeyHere
Defensive patterns
Strategy: validation
Validate before calling
// Fail fast at deploy time before starting the broker:
String secretKey = (String) conf.getProperty("tokenSecretKey");
String publicKey = (String) conf.getProperty("tokenPublicKey");
if ((secretKey == null || secretKey.isBlank()) && (publicKey == null || publicKey.isBlank())) {
throw new IllegalStateException(
"Token auth requires either tokenSecretKey or tokenPublicKey in the configuration");
} Try / catch
try {
authenticationProvider.initialize(conf);
} catch (IOException e) {
if (e.getMessage().contains("No secret key was provided")) {
throw new IllegalStateException("Set tokenSecretKey or tokenPublicKey in broker.conf before enabling token auth", e);
}
throw e;
} Prevention
- Generate and provision the key (bin/pulsar tokens create-secret-key) as part of deployment before enabling token auth.
- Keep tokenSecretKey/tokenPublicKey in a secrets store and template them into the conf, verifying the value is non-empty after substitution.
- Validate broker.conf in CI with a config lint that requires the key when the token auth provider is selected.
- Document that exactly one of tokenSecretKey / tokenPublicKey must be set.
When it happens
Trigger: The broker/client configuration sets authenticationProvider=org.apache.pulsar.broker.authentication.AuthenticationProviderToken (or the client sets the token auth provider) but neither tokenSecretKey nor tokenPublicKey is provided at initialize time.
Common situations: Enabling token authentication without supplying the secret key file/URL; key property name misspelled in conf; key file path exists but the property value is empty after env-var substitution; copying a config template that left the key fields blank.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid broker configuration. Authentication must be enabled
- No athenz domain name specified
- invalid algorithm provided ${tokenPublicAlg}
- Invalid proxy configuration. Authentication must be enabled
- No offloader found for driver '${driverName}'. Please make s
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/e12322d8c75e89b0.
Report an issue: GitHub.