SonarSource/sonarqube · error · UnsupportedCallbackException

Callback not supported

Error message

Callback not supported

What it means

CallbackHandlerImpl.handle throws UnsupportedCallbackException for any JAAS callback type other than NameCallback or PasswordCallback. The LDAP login module requested a callback this handler cannot answer (e.g. a TextOutputCallback or custom callback), so authentication cannot proceed with this handler implementation.

Source

Thrown at server/sonar-auth-ldap/src/main/java/org/sonar/auth/ldap/CallbackHandlerImpl.java:51

  private String name;
  private String password;

  public CallbackHandlerImpl(String name, String password) {
    this.name = name;
    this.password = password;
  }

  @Override
  public void handle(Callback[] callbacks) throws UnsupportedCallbackException, IOException {
    for (Callback callBack : callbacks) {
      switch (callBack) {
        case NameCallback nameCallback ->
          // Handles username callback
          nameCallback.setName(name);
        case PasswordCallback passwordCallback ->
          // Handles password callback
          passwordCallback.setPassword(password.toCharArray());
        case null, default -> throw new UnsupportedCallbackException(callBack, "Callback not supported");
      }
    }
  }
}

View on GitHub (pinned to 184c821202)

Solutions

  1. Inspect the UnsupportedCallbackException's callback class in the stack trace to identify which module requested it.
  2. Remove or reconfigure the JAAS module emitting the unsupported callback; use only standard NameCallback/PasswordCallback-based LDAP login modules.
  3. Update to a SonarQube version whose CallbackHandlerImpl supports the required callback types.
  4. If the callback is informational (TextOutputCallback), add a case to handle it before the default branch.

Example fix

// before
case null, default -> throw new UnsupportedCallbackException(callBack, "Callback not supported");
// after
case TextOutputCallback textCallback -> LOG.info("LDAP module: {}", textCallback.getMessage());
case null, default -> throw new UnsupportedCallbackException(callBack, "Callback not supported");
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the JAAS config only uses modules emitting NameCallback/PasswordCallback
for (Callback cb : callbacks) {
    if (!(cb instanceof NameCallback) && !(cb instanceof PasswordCallback)) {
        throw new IllegalStateException("Unsupported callback type: " + cb.getClass().getName());
    }
}

Try / catch

try {
    callbackHandler.handle(callbacks);
} catch (UnsupportedCallbackException e) {
    LOG.error("JAAS module requested unsupported callback: {}", e.getCallback().getClass().getName());
}

Prevention

When it happens

Trigger: handle(Callback[] callbacks, name, password) iterates callbacks; a switch case other than NameCallback/PasswordCallback/null reaches `case null, default -> throw new UnsupportedCallbackException(callBack, "Callback not supported")`.

Common situations: A JAAS/LDAP login module configured in the stack emits extra callbacks (e.g. language choice, text output for diagnostics, or a custom realm module) that the SonarQube LDAP CallbackHandler does not support; mixing third-party JAAS modules with the LDAP auth plugin.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/ca2192bd222a9e81. Report an issue: GitHub.