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 StringView on GitHub (pinned to 2add963021)
Solutions
- Ensure the client actually performs Kerberos (SPNEGO with KRB5 inner mech), e.g. configure the browser/client and disable NTLM fallback
- Before calling, sniff the token type: non-Negotiate or NTLMSSP signatures ('NTLMSSP\0') should be rejected early
- 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
- Ensure clients use real Kerberos (no NTLM fallback) before SPNEGO endpoints
- Pass the Authorization header payload base64-decoded and unmodified
- Reject NTLMSSP-prefixed tokens before any Kerberos parsing
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Not an AP-REQ token
- Tag not found: 0x${tags}
- Invalid SPNEGO sequence, 'WWW-Authenticate' header incorrect
- Invalid SPNEGO sequence, status code: {}
- oidName: ${oidName} is not supported.
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/f2d5b66d08cc7af9.
Report an issue: GitHub.