apache/pulsar · error · AuthenticationException
Invalid authentication token
Error message
Invalid authentication token
What it means
javax.naming.AuthenticationException thrown by SaslRoleToken.split when a '&'-separated segment of the token string contains no '=' character, meaning it is neither a key=value attribute pair nor parseable. split tokenizes on '&' and requires each part to have at least one '='; a bare fragment (e.g. "garbage" between '&' separators, or a value that itself contained '&' from an unvalidated token) triggers this before the attribute-set check in parse.
Source
Thrown at pulsar-broker-auth-sasl/src/main/java/org/apache/pulsar/broker/authentication/SaslRoleToken.java:217
/**
* Splits the string representation of a token into attributes pairs.
*
* @param tokenStr string representation of a token.
*
* @return a map with the attribute pairs of the token.
*
* @throws AuthenticationException thrown if the string representation of the token could not be broken into
* attribute pairs.
*/
private static Map<String, String> split(String tokenStr) throws AuthenticationException {
Map<String, String> map = new HashMap<String, String>();
StringTokenizer st = new StringTokenizer(tokenStr, ATTR_SEPARATOR);
while (st.hasMoreTokens()) {
String part = st.nextToken();
int separator = part.indexOf('=');
if (separator == -1) {
throw new AuthenticationException("Invalid authentication token");
}
String key = part.substring(0, separator);
String value = part.substring(separator + 1);
map.put(key, value);
}
return map;
}
}
View on GitHub (pinned to 820761864e)
Solutions
- Regenerate the token with SaslRoleToken/toString() so it contains only valid u=, i=, e= segments separated by '&', with no empty or '='-less segments
- Reject or sanitize any user-supplied component containing '&' before constructing the token (enforce checkForIllegalArgument on all inputs)
- Validate token shape before parsing: each '&'-separated part must contain '=' (regex like ^([^&=]+=[^&]*&)*[^&=]+=[^&]*$), else re-authenticate
- Catch AuthenticationException in the caller and return a clear invalid-token error so the client fetches a fresh token
Example fix
// before
SaslRoleToken token = SaslRoleToken.parse(tokenStr); // tokenStr may contain "u=bob&&i=1"
// after
if (Arrays.stream(tokenStr.split("&")).anyMatch(part -> !part.contains("="))) {
throw new AuthenticationException("Invalid authentication token");
}
SaslRoleToken token = SaslRoleToken.parse(tokenStr); Defensive patterns
Strategy: validation
Validate before calling
// run before SaslRoleToken.parse(tokenStr)
static boolean everySegmentHasKey(String tokenStr) {
if (tokenStr == null) return false;
for (String part : tokenStr.split("&", -1)) {
if (!part.contains("=")) return false; // empty or bare fragment
}
return true;
} Try / catch
try {
SaslRoleToken token = SaslRoleToken.parse(tokenStr);
} catch (AuthenticationException e) {
if (e.getMessage().equals("Invalid authentication token")) {
throw new AuthenticationException("Malformed token: a segment lacks '='; client must re-authenticate");
}
throw e;
} Prevention
- Never allow '&' inside token attribute values — enforce the checkForIllegalArgument rule on all inputs
- Reject tokens containing empty segments (consecutive '&') before parsing
- Build tokens exclusively via the SaslRoleToken constructors, never by string concatenation
- Treat parse failures as client errors and force a fresh authentication rather than retrying with the same token
When it happens
Trigger: Calling SaslRoleToken.parse(tokenStr) where any '&'-delimited segment lacks '=' — e.g. "u=bob&&i=1&e=9" (empty segment), "u=bob&i=1&e=9&extra" (trailing junk), or a token whose attribute value illegally contained '&' (bypassing checkForIllegalArgument) so the value split into fragments.
Common situations: Manually built or concatenated token strings; token values that legitimately contain '&' because producers skipped SaslRoleToken validation; corrupted/stored tokens with stray '&' or empty sections; clients sending arbitrary strings to the token endpoint probing the parser.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid token string, missing attributes
- Authentication use SASL/JAAS/GSSAPI but server not have Prin
- Unrecognized SASL GSSAPI Server Callback.
- ${name} is NULL, empty or contains a '&'
- Invalid signed text:
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/f804f423b31194b6.
Report an issue: GitHub.