shadow1ng/fscan · error
mssql: truncated us varchar
Error message
mssql: truncated us varchar
What it means
mssqlReadUSVarChar reads a UCS-2 string encoded as a 2-byte character count followed by count*2 bytes. It throws 'truncated us varchar' when fewer than 2 bytes remain to read even the length header. It is used by both mssqlParseErrorToken and mssqlSkipUSVarError, so this error means an ERROR/INFO token's message string header is missing from the payload.
Source
Thrown at plugins/services/mssql_raw.go:398
}
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")
}
return mssqlDecodeUCS2(payload[pos : pos+size]), pos + size, nil
}
func mssqlWritePacket(w io.Writer, packetType byte, payload []byte) error {
if len(payload)+8 > 0xffff {
return fmt.Errorf("mssql: packet too large")
}
header := []byte{packetType, tdsStatusEOM, 0, 0, 0, 0, 1, 0}
binary.BigEndian.PutUint16(header[2:4], uint16(len(payload)+8))
if _, err := w.Write(header); err != nil {
return errView on GitHub (pinned to 95cc12e753)
Solutions
- Retry the connection to rule out transient truncation.
- Verify your TDS packet reassembly honors total packet length and continuation packets.
- Capture the raw stream and confirm where the payload ends relative to the string header.
- If parsing your own buffered payload, check the buffer was fully populated before parsing tokens.
Example fix
// before: parse token strings assuming full payload
msg, _, err := mssqlReadUSVarChar(payload, pos)
// after: verify the 2-byte header fits before calling
if pos+2 > len(payload) {
return fmt.Errorf("cannot read error message: payload ends at %d", len(payload))
}
msg, _, err := mssqlReadUSVarChar(payload, pos) Defensive patterns
Strategy: validation
Validate before calling
if pos+2 > len(payload) {
return fmt.Errorf("US_VARCHAR header missing: need 2 bytes at offset %d, payload is %d", pos, len(payload))
}
chars := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))
if pos+2+chars*2 > len(payload) {
return fmt.Errorf("US_VARCHAR body of %d chars overruns payload", chars)
} Type guard
func hasUSVarChar(payload []byte, pos int) bool {
if pos+2 > len(payload) {
return false
}
return pos+2+int(binary.LittleEndian.Uint16(payload[pos:pos+2]))*2 <= len(payload)
} Try / catch
msg, next, err := mssqlReadUSVarChar(payload, pos)
if err != nil {
return fmt.Errorf("reading server error message failed: %w", err)
} Prevention
- Ensure TDS packet reassembly completes before parsing (handle continuation packets).
- Check both header and body bounds, not just the header.
- Use TLS so the string bytes cannot be altered in transit.
- Add parser unit tests with payloads cut exactly at string headers.
When it happens
Trigger: Either token parser positions the cursor at a US_VARCHAR whose 2-byte length header falls past the payload end (pos+2 > len(payload)).
Common situations: Server response truncated inside an ERROR/INFO token; man-in-the-middle or packet loss dropped the string header; fuzzed payloads ending mid-token; a custom packet reader assembled the login response incorrectly (e.g. wrong TDS packet reassembly).
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 token
- 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/e24b72878e8ea201.
Report an issue: GitHub.