shadow1ng/fscan · error
mssql: truncated token
Error message
mssql: truncated token
What it means
mssqlSkipLen16 advances past a token whose body is a 2-byte length prefix (used for fixed-length login-response tokens). If fewer than 2 bytes remain, the length header itself cannot be read and the library throws 'truncated token'. It guards the token walker in mssqlParseLoginTokens against running off the end of a truncated payload.
Source
Thrown at plugins/services/mssql_raw.go:386
if pos >= end {
return fmt.Errorf("mssql: truncated string in error token")
}
length := int(payload[pos]) * 2
pos++
if pos+length > end {
return fmt.Errorf("mssql: invalid string in error token")
}
pos += length
}
if pos+4 > end {
return fmt.Errorf("mssql: truncated error line number")
}
return nil
}
func mssqlSkipLen16(payload []byte, pos int) (int, error) {
if pos+2 > len(payload) {
return pos, fmt.Errorf("mssql: truncated token")
}
size := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))
next := pos + 2 + size
if next > len(payload) {
return pos, fmt.Errorf("mssql: invalid token size")
}
return next, nil
}
func mssqlReadUSVarChar(payload []byte, pos int) (string, int, error) {
if pos+2 > len(payload) {
return "", pos, fmt.Errorf("mssql: truncated us varchar")
}
chars := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))
pos += 2
size := chars * 2
if pos+size > len(payload) {
return "", pos, fmt.Errorf("mssql: invalid us varchar size")View on GitHub (pinned to 95cc12e753)
Solutions
- Retry the connection; transient truncation is the most common cause.
- Verify the port actually serves TDS SQL Server traffic.
- Increase proxy/LB idle timeouts if large login responses are being cut.
- Log the payload length and offset to confirm the response ended prematurely.
Example fix
// before: skip token without checking header availability
next, err := mssqlSkipLen16(payload, pos)
// after: bail out with context when the header is truncated
if len(payload)-pos < 2 {
return fmt.Errorf("login response ended at offset %d, token header truncated", pos)
}
next, err := mssqlSkipLen16(payload, pos) Defensive patterns
Strategy: try-catch
Validate before calling
if pos+2 > len(payload) {
return fmt.Errorf("token header truncated: payload has %d bytes, need %d", len(payload)-pos, 2)
} Type guard
func hasLen16Header(payload []byte, pos int) bool {
return pos+2 <= len(payload)
} Try / catch
next, err := mssqlSkipLen16(payload, pos)
if err != nil {
conn.Close()
return fmt.Errorf("truncated token in login response: %w", err)
} Prevention
- Fully buffer the login response (all TDS packets) before parsing tokens.
- Retry once on truncation; escalate if persistent.
- Raise proxy/LB timeouts for long-running login handshakes.
- Log payload size vs. consumed offset to detect systematic truncation.
When it happens
Trigger: mssqlParseLoginTokens calls mssqlSkipLen16 for a token type whose payload starts at pos with pos+2 > len(payload).
Common situations: The login response was cut off mid-stream by a network drop or proxy timeout; a non-TDS service on port 1433 emitted a short blob; fuzzed server sends a payload ending right before a token header.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- mssql: truncated error token
- mssql: truncated info token
- mssql: truncated us varchar
- mssql: invalid error token size
- mssql: invalid info token size
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/eae317081601034b.
Report an issue: GitHub.