apache/hadoop · error · AuthenticationException
'%s' did not handle the '%s' delegation token operation: %s
Error message
'%s' did not handle the '%s' delegation token operation: %s
What it means
During GETDELEGATIONTOKEN/RENEW (hasResponse=true), the client requires a JSON body and parses it with Jackson (JsonSerialization.mapReader().readValue(inputStream)). If the content-type claimed application/json but the body does not parse, the client throws AuthenticationException "'<authority>' did not handle the '<op>' delegation token operation: <cause>" - the server or an intermediary answered, but not with a parseable token response.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/web/DelegationTokenAuthenticator.java:337
// Unset delegation token to trigger fall-back authentication.
dt = ((DelegationTokenAuthenticatedURL.Token) token).getDelegationToken();
((DelegationTokenAuthenticatedURL.Token) token).setDelegationToken(null);
}
HttpURLConnection conn = null;
try {
conn = aUrl.openConnection(url, token);
conn.setRequestMethod(operation.getHttpMethod());
HttpExceptionUtils.validateResponse(conn, HttpURLConnection.HTTP_OK);
if (hasResponse) {
String contentType = conn.getHeaderField(CONTENT_TYPE);
contentType =
(contentType != null) ? StringUtils.toLowerCase(contentType) : null;
if (contentType != null &&
contentType.contains(APPLICATION_JSON_MIME)) {
try {
ret = JsonSerialization.mapReader().readValue(conn.getInputStream());
} catch (Exception ex) {
throw new AuthenticationException(String.format(
"'%s' did not handle the '%s' delegation token operation: %s",
url.getAuthority(), operation, ex.getMessage()), ex);
}
} else {
throw new AuthenticationException(String.format("'%s' did not " +
"respond with JSON to the '%s' delegation token operation",
url.getAuthority(), operation));
}
}
} finally {
if (dt != null) {
((DelegationTokenAuthenticatedURL.Token) token).setDelegationToken(dt);
}
if (conn != null) {
conn.disconnect();
}
}
return ret;View on GitHub (pinned to 2add963021)
Solutions
- Reproduce with curl -i --negotiate against the exact URL and inspect the raw body and Content-Type header.
- Bypass the proxy/gateway to confirm the Hadoop endpoint itself answers valid JSON, then fix proxy passthrough.
- Check the server log at that timestamp - the message embedded after ':' is the Jackson parse cause.
- Align client and server Hadoop versions if an upgrade is mid-flight.
Example fix
# before: opaque parse failure
# "'nn:1022' did not handle the 'GETDELEGATIONTOKEN' delegation token operation: Unexpected character ('<' ...)
curl -i --negotiate "http://nn:1022/webhdfs/v1/?op=GETDELEGATIONTOKEN&renewer=hdfs"
# after: inspection reveals the proxy prepends <html>; fix upstream to pass JSON through untouched Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight the endpoint with a raw HTTP client: any JSON op must answer JSON
HttpURLConnection c = (HttpURLConnection) url.openConnection();
String ct = c.getHeaderField("Content-Type");
if (ct == null || !ct.toLowerCase().contains("application/json")) {
throw new IOException("Endpoint " + url + " is not token-JSON (Content-Type: " + ct + ")");
} Try / catch
catch (AuthenticationException e) {
if (e.getMessage().contains("did not handle")) {
// body was not valid JSON: dump the raw response via curl, check proxies/gateway
}
throw e;
} Prevention
- Ensure gateways (Knox/nginx/SSL terminators) pass delegation-token responses through unmodified.
- Smoke-test GETDELEGATIONTOKEN with curl -i during deployment and assert Content-Type + parseable body.
- Pin client/server Hadoop versions during rolling upgrades.
When it happens
Trigger: doDelegationTokenOperation where conn content type contains application/json yet readValue fails: body is an HTML/text error mislabeled as JSON, truncated because the connection closed early, double-written by a proxy, or a different (older) server returning an incompatible payload.
Common situations: Gateway/proxy (Knox, nginx, SSL terminator) rewriting or padding responses; server returning an error page with a JSON content type; partial responses during network flaps; mixed-version clusters during rolling upgrades.
Related errors
- '%s' did not respond with JSON to the '%s' delegation token
- This should not happen: ${ex.getMessage()}
- request UGI cannot be NULL
- "Invalid Content-Length header: " + contentLength
- "Content-Length header is not provided by the server when tr
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/be5023fcf101de46.
Report an issue: GitHub.