apache/hadoop · error · IllegalArgumentException

Malformed gss token

Error message

Malformed gss token

What it means

KerberosUtil.getTokenServerName() walks the DER structure of a raw GSS token to extract the TGS server principal. After unwrapping an SPNEGO NegotiationToken the mechanism OID must be the Kerberos v5 OID; if the effective mechanism is not KRB5 (or the bytes do not decode as a Kerberos InitialContextToken), this IllegalArgumentException is thrown.

Source

Thrown at hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/KerberosUtil.java:320

    // DER encoding that will be extracted.
    DER token = new DER(rawToken);
    // InitialContextToken ::= [APPLICATION 0] IMPLICIT SEQUENCE {
    //     mech   OID
    //     mech-token  (NegotiationToken or InnerContextToken)
    // }
    DER oid = token.next();
    if (oid.equals(DER.SPNEGO_MECH_OID)) {
      // NegotiationToken ::= CHOICE {
      //     neg-token-init[0] NegTokenInit
      // }
      // NegTokenInit ::= SEQUENCE {
      //     mech-token[2]     InitialContextToken
      // }
      token = token.next().get(0xa0, 0x30, 0xa2, 0x04).next();
      oid = token.next();
    }
    if (!oid.equals(DER.KRB5_MECH_OID)) {
      throw new IllegalArgumentException("Malformed gss token");
    }
    // InnerContextToken ::= {
    //     token-id[1]
    //     AP-REQ
    // }
    if (token.next().getTag() != 1) {
      throw new IllegalArgumentException("Not an AP-REQ token");
    }
    // AP-REQ ::= [APPLICATION 14] SEQUENCE {
    //     ticket[3]      Ticket
    // }
    DER ticket = token.next().get(0x6e, 0x30, 0xa3, 0x61, 0x30);
    // Ticket ::= [APPLICATION 1] SEQUENCE {
    //     realm[1]       String
    //     sname[2]       PrincipalName
    // }
    // PrincipalName ::= SEQUENCE {
    //     name-string[1] SEQUENCE OF String

View on GitHub (pinned to 2add963021)

Solutions

  1. Ensure the client actually performs Kerberos (SPNEGO with KRB5 inner mech), e.g. configure the browser/client and disable NTLM fallback
  2. Before calling, sniff the token type: non-Negotiate or NTLMSSP signatures ('NTLMSSP\0') should be rejected early
  3. Verify the raw bytes are passed unmodified (correct base64 decoding of the Authorization header)

Example fix

// before
String server = KerberosUtil.getTokenServerName(rawToken); // may throw for NTLM

// after: only attempt Kerberos extraction for Kerberos tokens
if (rawToken.length > 7 && new String(rawToken, 0, 7, US_ASCII).equals("NTLMSSP")) {
  throw new AuthenticationException("NTLM not supported");
}
String server = KerberosUtil.getTokenServerName(rawToken);
Defensive patterns

Strategy: try-catch

Validate before calling

boolean probablyKerberosNegotiate(byte[] raw) {
  if (raw == null || raw.length < 2) return false;
  if (raw.length > 7 && (raw[0]&0xff)=='N' && (raw[1]&0xff)=='T' && (raw[2]&0xff)=='L') return false; // NTLMSSP
  return (raw[0] & 0xff) == 0x60 || (raw[0] & 0xff) == 0xa0; // InitialContextToken / negTokenInit
}

Try / catch

try { server = KerberosUtil.getTokenServerName(rawToken); } catch (IllegalArgumentException e) { /* non-Kerberos or undecodable: respond 401 with Negotiate header */ }

Prevention

When it happens

Trigger: Calling getTokenServerName(rawToken) with a Negotiate token whose inner mechanism is NTLM or another non-Kerberos mech; feeding arbitrary bytes or an SPNEGO negTokenResp (response) instead of negTokenInit; a truncated token buffer.

Common situations: Browsers authenticating with NTLM over Negotiate hitting an SPNEGO endpoint that assumes Kerberos; custom GSS clients sending raw non-Kerberos contexts; middleware dropping trailing bytes of the Authorization header payload.

Understand the failure class

Related errors


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