apache/hadoop · critical · SaslException

Client mechanism is malformed

Error message

Client mechanism is malformed

What it means

In processSaslMessage's INITIATE case, the client's SASL INITIATE message must carry exactly one auth mechanism entry (getAuthsCount() == 1); zero or multiple entries throw SaslException("Client mechanism is malformed"). After that count check, the single mechanism is validated against the methods the server advertised.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java:2416

      final SaslState state = saslMessage.getState(); // required      
      switch (state) {
        case NEGOTIATE: {
          if (sentNegotiate) {
            // FIXME shouldn't this be SaslException?
            throw new AccessControlException(
                "Client already attempted negotiation");
          }
          saslResponse = buildSaslNegotiateResponse();
          // simple-only server negotiate response is success which client
          // interprets as switch to simple
          if (saslResponse.getState() == SaslState.SUCCESS) {
            switchToSimple();
          }
          break;
        }
        case INITIATE: {
          if (saslMessage.getAuthsCount() != 1) {
            throw new SaslException("Client mechanism is malformed");
          }
          // verify the client requested an advertised authType
          SaslAuth clientSaslAuth = saslMessage.getAuths(0);
          if (!negotiateResponse.getAuthsList().contains(clientSaslAuth)) {
            if (sentNegotiate) {
              throw new AccessControlException(
                  clientSaslAuth.getMethod() + " authentication is not enabled."
                      + "  Available:" + enabledAuthMethods);
            }
            saslResponse = buildSaslNegotiateResponse();
            break;
          }
          authMethod = AuthMethod.valueOf(clientSaslAuth.getMethod());
          // abort SASL for SIMPLE auth, server has already ensured that
          // SIMPLE is a legit option above.  we will send no response
          if (authMethod == AuthMethod.SIMPLE) {
            switchToSimple();
            saslResponse = null;

View on GitHub (pinned to 2add963021)

Solutions

  1. Send exactly one SaslAuth in INITIATE, copied from one entry of the server's negotiate response.
  2. Use the standard client libraries to build and serialize the SASL handshake.
  3. Align client and server Hadoop versions so the RpcSaslProto definitions match.

Example fix

// before — malformed INITIATE (zero or multiple auths)
RpcSaslProto.Builder b = RpcSaslProto.newBuilder()
    .setState(SaslState.INITIATE); // no addAuths, or addAuths called twice
// after — exactly one mechanism
RpcSaslProto.Builder b = RpcSaslProto.newBuilder()
    .setState(SaslState.INITIATE)
    .addAuths(RpcSaslProto.SaslAuth.newBuilder()
        .setMethod(authMethod)
        .setMechanism(mechanism));
Defensive patterns

Strategy: validation

Validate before calling

RpcSaslProto initiate = buildInitiate(selectedAuth);
if (initiate.getAuthsCount() != 1) {
  throw new IllegalStateException(
      "INITIATE must carry exactly one auth mechanism, got "
          + initiate.getAuthsCount());
}
send(initiate);

Prevention

When it happens

Trigger: A client building RpcSaslProto INITIATE with no SaslAuth or with several: hand-written or native clients constructing the protobuf manually, schema/version skew producing wrong field counts, or corrupted frames on the wire.

Common situations: Non-Java or custom clients implementing the Hadoop SASL protocol directly; mismatched Hadoop protobuf definitions between client and server; protocol bridges that mangle the INITIATE message.

Understand the failure class

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/e8273e2cce0be155. Report an issue: GitHub.