shadow1ng/fscan · error

mssql: truncated info token

Error message

mssql: truncated info token

What it means

mssqlSkipUSVarError skips over an informational (INFO token, 0xAB) message in the login response, but fewer than 2 bytes remain, so the 2-byte token length header cannot be read. Like the ERROR-token variant, this is a boundary check that fails when the payload ends mid-token, signaling a truncated or corrupt server response rather than caller error.

Source

Thrown at plugins/services/mssql_raw.go:355

	size := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))
	end := pos + 2 + size
	if size < 6 || end > len(payload) || pos+8 > len(payload) {
		return mssqlRawError{}, pos, fmt.Errorf("mssql: invalid error token size")
	}
	pos += 2
	number := int32(binary.LittleEndian.Uint32(payload[pos : pos+4]))
	pos += 4
	pos += 2
	message, next, err := mssqlReadUSVarChar(payload, pos)
	if err != nil {
		return mssqlRawError{}, pos, err
	}
	return mssqlRawError{number: number, message: message}, end, mssqlEnsureSkipBVarStrings(payload, next, end)
}

func mssqlSkipUSVarError(payload []byte, pos int) (int, error) {
	if pos+2 > len(payload) {
		return pos, fmt.Errorf("mssql: truncated info token")
	}
	size := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))
	end := pos + 2 + size
	if size < 6 || end > len(payload) || pos+8 > len(payload) {
		return pos, fmt.Errorf("mssql: invalid info token size")
	}
	_, _, err := mssqlReadUSVarChar(payload, pos+8)
	return end, err
}

func mssqlEnsureSkipBVarStrings(payload []byte, pos, end int) error {
	for i := 0; i < 2; i++ {
		if pos >= end {
			return fmt.Errorf("mssql: truncated string in error token")
		}
		length := int(payload[pos]) * 2
		pos++
		if pos+length > end {

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Reconnect and retry; truncation is usually transient.
  2. Confirm the endpoint is a real SQL Server speaking TDS on the configured port.
  3. Enable packet capture to find what is truncating the TCP stream.
  4. If reproducible with a specific server, report/patch the server-side token emission bug.
Defensive patterns

Strategy: try-catch

Validate before calling

if len(payload)-pos < 2 {
    return fmt.Errorf("INFO token header truncated at offset %d", pos)
}

Type guard

func hasInfoTokenHeader(payload []byte, pos int) bool {
    return pos+2 <= len(payload)
}

Try / catch

next, err := mssqlSkipUSVarError(payload, pos)
if err != nil {
    // truncated INFO token: response stream is corrupt
    return fmt.Errorf("skipping INFO token failed: %w", err)
}

Prevention

When it happens

Trigger: mssqlParseLoginTokens walks token stream and hits an INFO token whose position leaves less than 2 bytes in the payload (pos+2 > len(payload)).

Common situations: Network stack or proxy truncated the login response; server sent an informational message (e.g. 'changed database context') as the final bytes and the stream was cut; fuzzing or a non-TDS service responding on port 1433.

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


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/38db38e67523872a. Report an issue: GitHub.