{"record":{"id":"a2f1ebe2a3be1b19","repo":"shadow1ng/fscan","slug":"mssql-unexpected-login-token-0x-02x","errorCode":null,"errorMessage":"mssql: unexpected login token 0x%02x","messagePattern":"mssql: unexpected login token 0x%02x","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/mssql_raw.go","lineNumber":327,"sourceCode":"\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tpos = next\n\t\tcase tdsTokenLoginAck:\n\t\t\tnext, err := mssqlSkipLen16(payload, pos)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tresult.sawLoginAck = true\n\t\t\tpos = next\n\t\tcase tdsTokenDone, tdsTokenDoneProc, tdsTokenDoneInProc:\n\t\t\tif pos+12 > len(payload) {\n\t\t\t\treturn false, fmt.Errorf(\"mssql: truncated done token\")\n\t\t\t}\n\t\t\tstatus := binary.LittleEndian.Uint16(payload[pos : pos+2])\n\t\t\treturn status&(tdsDoneError|tdsDoneSrvError) == 0, nil\n\t\tdefault:\n\t\t\treturn false, fmt.Errorf(\"mssql: unexpected login token 0x%02x\", token)\n\t\t}\n\t}\n\treturn false, nil\n}\n\nfunc mssqlParseErrorToken(payload []byte, pos int) (mssqlRawError, int, error) {\n\tif pos+2 > len(payload) {\n\t\treturn mssqlRawError{}, pos, fmt.Errorf(\"mssql: truncated error token\")\n\t}\n\tsize := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))\n\tend := pos + 2 + size\n\tif size < 6 || end > len(payload) || pos+8 > len(payload) {\n\t\treturn mssqlRawError{}, pos, fmt.Errorf(\"mssql: invalid error token size\")\n\t}\n\tpos += 2\n\tnumber := int32(binary.LittleEndian.Uint32(payload[pos : pos+4]))\n\tpos += 4\n\tpos += 2","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/mssql_raw.go#L309-L345","documentation":"The login response contained a TDS token the parser does not understand. This minimal raw-login implementation only handles error/info/envchange/loginack/done tokens, so any other token in the login response aborts parsing.","triggerScenarios":"mssqlParseLoginTokens' default branch fires on token bytes such as 0x81 (COLMETADATA), 0x81/0xA9/0xA8 result tokens, or SSPI (0xED) — typically when the server wants integrated auth or returns result sets during login.","commonSituations":"Windows/SSPI authentication requested by the server (token 0xED); servers emitting features this minimal client didn't negotiate; truly desynchronized/garbage streams.","solutions":["Check whether the server demands SSPI/Kerberos — if so, SQL auth cannot complete without implementing token 0xED handling; use go-mssqldb with Integrated Security instead.","Add a case for the reported token type (it is printed in the error) if it is benign and can be safely skipped.","Verify TDS version negotiation — some tokens only appear at higher TDS versions.","Capture the stream and confirm the token byte is where parsing believes it is (a prior token mis-skip can desynchronize the walk)."],"exampleFix":"// before\ndefault:\n    return false, fmt.Errorf(\"mssql: unexpected login token 0x%02x\", token)\n// after\ncase 0xed: // SSPI — not supported by this raw client\n    return false, fmt.Errorf(\"mssql: server requested SSPI authentication; use SQL auth or a full driver\")\ndefault:\n    return false, fmt.Errorf(\"mssql: unexpected login token 0x%02x\", token)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, err := mssqlRawLogin(ctx, host, port, user, pass, timeout)\nif err != nil {\n    var tok byte\n    if n, _ := fmt.Sscanf(err.Error(), \"mssql: unexpected login token 0x%02x\", &tok); n == 1 && tok == 0xed {\n        return fmt.Errorf(\"server requires SSPI auth; use a full driver\")\n    }\n    return err\n}","preventionTips":["Use SQL authentication accounts (not Windows-integrated) when probing with this raw client.","Extend the token switch when new server features emit extra tokens.","Read the token hex in the error message to identify what the server sent."],"tags":["mssql","tds","login","token","protocol"],"backgroundTag":"unexpected-response-shape","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}