apache/hadoop · error · UnsupportedCallbackException
Unrecognized SASL client callback
Error message
Unrecognized SASL client callback
What it means
SaslRpcClient.AuthenticatorCallbackHandler only implements NameCallback, PasswordCallback, RealmCallback and AuthorizeCallback. When the JVM's SASL framework hands it any other Callback type (e.g. RealmChoiceCallback from a DIGEST-MD5 exchange), it throws UnsupportedCallbackException with this message. It signals that the negotiated SASL mechanism expects more from the client than Hadoop's handler was built to provide.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SaslRpcClient.java:694
for (Callback callback : callbacks) {
if (callback instanceof RealmChoiceCallback) {
continue;
} else if (callback instanceof NameCallback) {
nc = (NameCallback) callback;
} else if (callback instanceof PasswordCallback) {
pc = (PasswordCallback) callback;
} else if (callback instanceof RealmCallback) {
rc = (RealmCallback) callback;
} else if (callback instanceof AuthorizeCallback) {
final AuthorizeCallback ac = (AuthorizeCallback) callback;
final String authId = ac.getAuthenticationID();
final String authzId = ac.getAuthorizationID();
ac.setAuthorized(authId.equals(authzId));
if (ac.isAuthorized()) {
ac.setAuthorizedID(authzId);
}
} else {
throw new UnsupportedCallbackException(callback,
"Unrecognized SASL client callback " + callback.getClass());
}
}
if (nc != null) {
if (LOG.isDebugEnabled())
LOG.debug("SASL client callback: setting username: " + userName);
nc.setName(userName);
}
if (pc != null) {
if (LOG.isDebugEnabled())
LOG.debug("SASL client callback: setting userPassword");
pc.setPassword(userPassword);
}
if (rc != null) {
if (LOG.isDebugEnabled())
LOG.debug("SASL client callback: setting realm: "
+ rc.getDefaultText());
rc.setText(rc.getDefaultText());View on GitHub (pinned to 2add963021)
Solutions
- Note the callback class named in the message and identify the mechanism in use (GSSAPI = KERBEROS, DIGEST-MD5 = TOKEN, PLAIN = SIMPLE over SASL)
- Remove third-party SASL providers from the JVM security configuration so JDK defaults apply
- Make client and server run compatible Hadoop versions with the same hadoop.security.authentication setting
- If you control a custom SaslClientFactory, extend SaslRpcClient's callback handler to accept the missing callback type
Defensive patterns
Strategy: try-catch
Try / catch
try {
proxy = RPC.getProtocolProxy(proto, addr, ticket, conf);
} catch (IOException e) {
Throwable root = e;
while (root.getCause() != null) root = root.getCause();
if (root instanceof UnsupportedCallbackException) {
// unsupported SASL callback: check mechanism/provider setup, do not retry blindly
throw new SecurityException("SASL callback not supported: " + root.getMessage(), e);
}
throw e;
} Prevention
- Keep client and server Hadoop versions and hadoop.security.authentication settings identical
- Do not register third-party SASL providers in the JVM security config
- Re-test the full SASL handshake in staging after JDK or Hadoop upgrades
When it happens
Trigger: Establishing an RPC connection where the negotiated mechanism emits a callback outside the four supported types: a DIGEST-MD5 (TOKEN auth) exchange where the JDK passes RealmChoiceCallback, or a custom/extra SASL mechanism registered in java.security that requests additional callbacks during Sasl.createSaslClient negotiation.
Common situations: Mismatched Hadoop client/server versions negotiating different mechanisms, a JVM with non-standard or third-party SASL providers, custom authentication plugins, or JDK upgrades that change which callbacks the SASL factories emit.
Related errors
- Client did not send a token
- Server asks us to fall back to SIMPLE auth, but this client
- Can't retrieve username from tokenIdentifier.
- ${method} authentication is not enabled. Available:${enable
- Client sent unsupported state ${state}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/e793cd5b7c5b4e9a.
Report an issue: GitHub.