apache/hadoop · error · IllegalStateException
Failed to get method
Error message
Failed to get method
What it means
CustomizedCallbackHandler.delegate(Object) adapts any object into the handler interface by reflectively locating a public method named handleCallbacks with the exact signature (List, String, char[]). If no such method exists on the delegated object's class, an IllegalStateException is thrown at adapter-creation time. This is a programming/wiring error: the configured class was instantiated fine but does not expose the expected reflective contract.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/CustomizedCallbackHandler.java:103
@Override
public void handleCallbacks(List<Callback> callbacks, String username, char[] password)
throws UnsupportedCallbackException {
if (!callbacks.isEmpty()) {
final Callback cb = callbacks.get(0);
throw new UnsupportedCallbackException(callbacks.get(0),
"Unsupported callback: " + (cb == null ? null : cb.getClass()));
}
}
}
static CustomizedCallbackHandler delegate(Object delegated) {
final String methodName = "handleCallbacks";
final Class<?> clazz = delegated.getClass();
final Method method;
try {
method = clazz.getMethod(methodName, List.class, String.class, char[].class);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("Failed to get method " + methodName + " from " + clazz, e);
}
return (callbacks, name, password) -> {
try {
method.invoke(delegated, callbacks, name, password);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IOException("Failed to invoke " + method, e);
}
};
}
static CustomizedCallbackHandler get(String key, Configuration conf) {
return Cache.get(key, conf);
}
void handleCallbacks(List<Callback> callbacks, String name, char[] password)
throws UnsupportedCallbackException, IOException;
}View on GitHub (pinned to 2add963021)
Solutions
- Add a public method exactly matching: public void handleCallbacks(java.util.List<javax.security.auth.callback.Callback> callbacks, String username, char[] password)
- Alternatively make the class directly implement org.apache.hadoop.security.CustomizedCallbackHandler so the delegate reflection path is never used
- Check for accidental overloading (e.g. handleCallbacks(List, String, char[]) plus a legacy handleCallbacks(Callback[], ...)) and ensure the wanted one is public
- Redeploy the fixed jar to the server classpath and restart
Example fix
// before: signature mismatch, getMethod() fails
public void handleCallbacks(List<NameCallback> callbacks,
String user, char[] pw) { ... }
// after: exact reflective contract
public void handleCallbacks(List<Callback> callbacks,
String user, char[] pw)
throws UnsupportedCallbackException, IOException { ... } Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = Class.forName(configuredHandlerClass);
boolean implementsIface = CustomizedCallbackHandler.class.isAssignableFrom(c);
boolean hasReflectiveMethod = false;
try {
c.getMethod("handleCallbacks", List.class, String.class, char[].class);
hasReflectiveMethod = true;
} catch (NoSuchMethodException ignored) { }
if (!implementsIface && !hasReflectiveMethod) {
throw new IllegalStateException(configuredHandlerClass
+ " must implement CustomizedCallbackHandler or expose "
+ "public handleCallbacks(List, String, char[])");
} Type guard
static boolean isValidHandlerClass(Class<?> c) {
if (CustomizedCallbackHandler.class.isAssignableFrom(c)) return true;
try { c.getMethod("handleCallbacks", List.class, String.class, char[].class); return true; }
catch (NoSuchMethodException e) { return false; }
} Try / catch
try {
CustomizedCallbackHandler.delegate(target);
} catch (IllegalStateException e) {
// add the public handleCallbacks(List, String, char[]) method
// or implement the interface directly
LOG.error("Handler class lacks handleCallbacks(List,String,char[]): {}", e.getMessage());
} Prevention
- Match the reflective signature exactly: java.util.List, String, char[], public visibility
- Prefer implementing the interface over relying on reflection
- Add a config-deployment check that validates the handler class at rollout, before SASL handshakes hit it
When it happens
Trigger: Setting hadoop.security.sasl.CustomizedCallbackHandler.class to a class that does NOT implement CustomizedCallbackHandler AND has no public handleCallbacks(List<Callback>, String, char[]) method — Cache.getSynchronously instantiates it and calls CustomizedCallbackHandler.delegate(created), which throws. Also triggered by signature mismatches: wrong parameter types, extra parameters, or a non-public method (getMethod only finds public ones).
Common situations: Copy-pasting a handler from an older Hadoop with a different method signature; implementing handleCallbacks with concrete List implementations instead of java.util.List; making the method package-private or static-only; third-party handler jars built against a different branch.
Related errors
- Failed to invoke
- Server asks us to fall back to SIMPLE auth, but this client
- Error creating plugin: {}
- Unsupported callback:
- Failed to create {clazz}:{e}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/c96862ee399b6621.
Report an issue: GitHub.