apache/hadoop · error · IOException
Usernames not matched: name={shortName} != expected={expecte
Error message
Usernames not matched: name={shortName} != expected={expected} What it means
The second branch of JspHelper.checkUsername: when both names exist, 'name' is normalized through KerberosName.getShortName() (applying hadoop auth_to_local rules) and compared to 'expected'; any difference throws IOException('Usernames not matched: name=X != expected=Y'). In DataNodeUGIProvider (line 146) the token owner's short name is expected, and the user.name query parameter is the name being checked, so a user.name that disagrees with the delegation token's identity is refused.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/JspHelper.java:220
return request.getRemotePort();
}
/**
* Expected user name should be a short name.
*/
public static void checkUsername(final String expected, final String name
) throws IOException {
if (expected == null && name != null) {
throw new IOException("Usernames not matched: expecting null but name="
+ name);
}
if (name == null) { //name is optional, null is okay
return;
}
KerberosName u = new KerberosName(name);
String shortName = u.getShortName();
if (!shortName.equals(expected)) {
throw new IOException("Usernames not matched: name=" + shortName
+ " != expected=" + expected);
}
}
private static String getUsernameFromQuery(final HttpServletRequest request,
final boolean tryUgiParameter) {
String username = request.getParameter(UserParam.NAME);
if (username == null && tryUgiParameter) {
//try ugi parameter
final String ugiStr = request.getParameter("ugi");
if (ugiStr != null) {
username = ugiStr.split(",")[0];
}
}
return username;
}
}View on GitHub (pinned to 2add963021)
Solutions
- Remove or correct the user.name parameter so it equals the token owner's short name (or simply omit it)
- After changing hadoop.security.auth_to_local, re-kinit and obtain new delegation tokens so identities agree
- Standardize on token/SPNEGO identity and stop sending user.name in secured deployments
Example fix
# before: token owner is alice, url says bob curl 'http://dn:9864/webhdfs/v1/f?op=OPEN&delegation=<token>&user.name=bob' # after curl 'http://dn:9864/webhdfs/v1/f?op=OPEN&delegation=<token>'
Defensive patterns
Strategy: try-catch
Validate before calling
String expected = tokenUgi.getShortUserName();
String name = request.getParameter(UserParam.NAME);
if (name != null && expected != null) {
String shortName = new KerberosName(name).getShortName();
if (!shortName.equals(expected)) {
resp.sendError(403, "user.name " + shortName + " != token owner " + expected);
return;
}
} Try / catch
try {
JspHelper.checkUsername(ugi.getShortUserName(), usernameFromQuery);
} catch (IOException e) {
if (e.getMessage().startsWith("Usernames not matched:")) {
resp.sendError(403, "supplied user.name does not match the authenticated identity");
} else throw e;
} Prevention
- Strip user.name from client URLs once Kerberos is enabled
- After changing auth_to_local rules, re-issue delegation tokens so short names agree
- Log both sides of the comparison on mismatch to catch rule-mapping drift quickly
When it happens
Trigger: Secured DataNode WebHDFS request whose delegation token belongs to user A but whose user.name parameter says user B after short-name rules (e.g., token for alice@REALM -> 'alice' vs user.name=bob); or auth_to_local rule changes that make the same principal's short name differ from what the client sends.
Common situations: Client libraries or browsers appending a stale user.name to DataNode URLs; auth_to_local rules changed after tokens were issued; cross-realm principals whose short-name mapping differs between client and cluster.
Related errors
- Usernames not matched: expecting null but name={name}
- Fetch of delegation token failed
- Security is enabled but block access tokens (via dfs.block.a
- Unable to bind on specified streaming port in secure context
- Unable to bind on specified info port in secure context. Nee
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/8c33db1cb944aaa9.
Report an issue: GitHub.