{"record":{"id":"8c9b0396bfe27239","repo":"apache/hadoop","slug":"unsupported-callback","errorCode":null,"errorMessage":"Unsupported callback: ","messagePattern":"Unsupported callback: ","errorType":"exception","errorClass":"UnsupportedCallbackException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/CustomizedCallbackHandler.java","lineNumber":90,"sourceCode":"      return cached != null ? cached : getSynchronously(key, conf);\n    }\n\n    public static synchronized void clear() {\n      MAP.clear();\n    }\n\n    private Cache() { }\n  }\n\n  class DefaultHandler implements CustomizedCallbackHandler {\n    private static final DefaultHandler INSTANCE = new DefaultHandler();\n\n    @Override\n    public void handleCallbacks(List<Callback> callbacks, String username, char[] password)\n        throws UnsupportedCallbackException {\n      if (!callbacks.isEmpty()) {\n        final Callback cb = callbacks.get(0);\n        throw new UnsupportedCallbackException(callbacks.get(0),\n            \"Unsupported callback: \" + (cb == null ? null : cb.getClass()));\n      }\n    }\n  }\n\n  static CustomizedCallbackHandler delegate(Object delegated) {\n    final String methodName = \"handleCallbacks\";\n    final Class<?> clazz = delegated.getClass();\n    final Method method;\n    try {\n      method = clazz.getMethod(methodName, List.class, String.class, char[].class);\n    } catch (NoSuchMethodException e) {\n      throw new IllegalStateException(\"Failed to get method \" + methodName + \" from \" + clazz, e);\n    }\n\n    return (callbacks, name, password) -> {\n      try {\n        method.invoke(delegated, callbacks, name, password);","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/CustomizedCallbackHandler.java#L72-L108","documentation":"Hadoop's SASL DIGEST-MD5 server callback machinery supports pluggable callback handlers via hadoop.security.sasl.CustomizedCallbackHandler.class. When no custom handler is configured (or the configured class could not be instantiated), the built-in DefaultHandler is used, and it rejects every callback it is handed. The exception names the exact callback class that was unsupported, which tells you which SASL callback type arrived. Empty callback lists pass through silently; any non-empty list throws.","triggerScenarios":"A SASL handshake reaches SaslDigestCallbackHandler (e.g. a TokenIdentifier-based DIGEST-MD5 exchange in SaslRpcServer) and dispatches callbacks (NameCallback/PasswordCallback/AuthorizeCallback) to CustomizedCallbackHandler.get(...) while hadoop.security.sasl.CustomizedCallbackHandler.class is unset, set to an empty value, or points at a class whose instantiation failed (the cache silently falls back to DefaultHandler with only a WARN log).","commonSituations":"Clusters running token-based (DIGEST-MD5) authentication where an integration expects a custom handler to answer callbacks but the key was omitted from the server's core-site.xml; typos in the class name causing instantiation failure and silent fallback; upgrading Hadoop versions where the property name changed.","solutions":["Set hadoop.security.sasl.CustomizedCallbackHandler.class in core-site.xml to a class that implements CustomizedCallbackHandler (or exposes handleCallbacks(List<Callback>, String, char[])) and restart the service","If you configured a class already, check the server log for 'Failed to create a new instance of ... fallback to DefaultHandler' — fix the NoClassDefFound/constructor access issue so your class actually loads","Ensure your handler actually consumes the callback type shown in the message (the exception prints cb.getClass()) instead of rethrowing","If you never intended custom callbacks, investigate why the client is negotiating an auth path that requires them (e.g. DIGEST-MD5 with tokens) and switch to KERBEROS or SIMPLE as appropriate"],"exampleFix":"# before (core-site.xml): handler missing, DefaultHandler throws\n# after\n<property>\n  <name>hadoop.security.sasl.CustomizedCallbackHandler.class</name>\n  <value>com.mycompany.MyDigestCallbackHandler</value>\n</property>\n\n// handler must implement the interface or expose the reflective method\npublic class MyDigestCallbackHandler\n    implements CustomizedCallbackHandler {\n  @Override\n  public void handleCallbacks(List<Callback> callbacks, String username,\n      char[] password) throws UnsupportedCallbackException {\n    for (Callback cb : callbacks) {\n      if (cb instanceof AuthorizeCallback) {\n        ((AuthorizeCallback) cb).setAuthorized(true);\n      } else {\n        throw new UnsupportedCallbackException(cb);\n      }\n    }\n  }\n}","handlingStrategy":"validation","validationCode":"// before handing callbacks to the handler\nCustomizedCallbackHandler h =\n    CustomizedCallbackHandler.get(\n        CommonConfigurationKeysPublic.HADOOP_SECURITY_SASL_CUSTOMIZEDCALLBACKHANDLER_CLASS_KEY,\n        conf);\nif (h instanceof CustomizedCallbackHandler.DefaultHandler\n    && !callbacks.isEmpty()) {\n  // DefaultHandler will throw UnsupportedCallbackException\n  LOG.warn(\"No customized callback handler configured; \"\n      + \"DIGEST-MD5 callbacks of type \" + callbacks.get(0).getClass()\n      + \" will be rejected\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  handler.handleCallbacks(callbacks, user, password);\n} catch (UnsupportedCallbackException e) {\n  // e.getCallback() names the offending callback; log and abort the SASL step\n  LOG.error(\"Callback rejected: {}\", e.getCallback().getClass(), e);\n  throw e;\n}","preventionTips":["Configure hadoop.security.sasl.CustomizedCallbackHandler.class whenever token-based DIGEST-MD5 is used with non-standard callbacks","Watch startup logs for 'Failed to create a new instance of ... fallback to DefaultHandler' — silent fallback is the usual precursor","Write a smoke test that calls handleCallbacks with each callback type your handshake produces"],"tags":["sasl","authentication","callback","digest-md5","hadoop"],"backgroundTag":"sasl-callback-unsupported","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}