apache/pulsar · error · IllegalArgumentException
${name} is NULL, empty or contains a '&'
Error message
${name} is NULL, empty or contains a '&' What it means
IllegalArgumentException from SaslRoleToken.checkForIllegalArgument, thrown by the SaslRoleToken constructors when userRole or session is null, empty, or contains the '&' attribute separator character. '&' is the delimiter used in the serialized token string (u=..&i=..&e=..), so a value containing it would corrupt the token format and is rejected up front.
Source
Thrown at pulsar-broker-auth-sasl/src/main/java/org/apache/pulsar/broker/authentication/SaslRoleToken.java:94
public SaslRoleToken(String userRole, String session, long expires) {
checkForIllegalArgument(userRole, "userRole");
checkForIllegalArgument(session, "session");
this.userRole = userRole;
this.session = session;
this.expires = expires;
generateToken();
}
/**
* Check if the provided value is invalid. Throw an error if it is invalid, NOP otherwise.
*
* @param value the value to check.
* @param name the parameter name to use in an error message if the value is invalid.
*/
private static void checkForIllegalArgument(String value, String name) {
if (value == null || value.length() == 0 || value.contains(ATTR_SEPARATOR)) {
throw new IllegalArgumentException(name + ILLEGAL_ARG_MSG);
}
}
/**
* Sets the expiration of the token.
*
* @param expires expiration time of the token in milliseconds since the epoch.
*/
public void setExpires(long expires) {
if (this != SaslRoleToken.ANONYMOUS) {
this.expires = expires;
generateToken();
}
}
/**
* Generates the token.
*/View on GitHub (pinned to 820761864e)
Solutions
- Validate inputs before constructing: reject or sanitize values that are null, empty, or contain '&' (URL-encode or strip the character)
- Use a generated session identifier (UUID or similar) rather than assembling one from user-controlled strings
- If '&' must be preserved in userRole, escape/encode it (e.g. percent-encoding) before constructing the token and decode after parse
- Catch IllegalArgumentException at the API boundary and return a 4xx-style authentication error identifying the offending parameter
Example fix
// before
SaslRoleToken token = new SaslRoleToken(userName, sessionId); // throws if userName is null or contains '&'
// after
if (userName == null || userName.isEmpty() || userName.contains("&")) {
throw new IllegalArgumentException("userRole is NULL, empty or contains a '&'");
}
String safeUserName = URLEncoder.encode(userName, StandardCharsets.UTF_8);
SaslRoleToken token = new SaslRoleToken(safeUserName, sessionId); Defensive patterns
Strategy: validation
Validate before calling
// run before new SaslRoleToken(userRole, session[, expires])
static void validateTokenInput(String userRole, String session) {
if (userRole == null || userRole.isEmpty() || userRole.contains("&")) {
throw new IllegalArgumentException("userRole is NULL, empty or contains a '&'");
}
if (session == null || session.isEmpty() || session.contains("&")) {
throw new IllegalArgumentException("session is NULL, empty or contains a '&'");
}
} Try / catch
try {
SaslRoleToken token = new SaslRoleToken(userRole, session);
} catch (IllegalArgumentException e) {
// parameter name is prefixed in the message ("session is NULL, empty or contains a '&'")
throw new AuthenticationException("Invalid token parameter: " + e.getMessage());
} Prevention
- Sanitize or URL-encode user-supplied role names so they never contain '&'
- Generate session ids with UUID.randomUUID() instead of concatenating user data
- Remember the 2-arg constructor validates only session — validate userRole yourself before calling it
- Add a unit test covering null, empty, and '&' inputs for both constructors
When it happens
Trigger: new SaslRoleToken(userRole, session) with null/empty session or a session containing '&' (the 2-arg constructor checks session only); new SaslRoleToken(userRole, session, expires) with null/empty userRole or session or either containing '&' (e.g. a Kerberos principal like user/host@REALM isn't affected, but a name containing '&' is); SaslRoleToken.parse passing a value extracted from a malformed token string into the constructor.
Common situations: Caller builds a token from unvalidated user input where the username contains '&' (e.g. a display name or email-derived role); session id accidentally built by joining values with '&'; a null/empty session because the upstream authentication step produced no session identifier; unit/custom code constructing tokens by hand.
Related errors
- Invalid range ${range}
- Split service unit should be split into 2 service units.
- ResourceGroupCreate: Invalid null ResourceGroup config
- ResourceGroupCreate: can't create resource group with an emp
- Invalid token string, missing attributes
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/96e822421a588c64.
Report an issue: GitHub.