shadow1ng/fscan · error

mssql: truncated error line number

Error message

mssql: truncated error line number

What it means

After the two BVarChar strings, a TDS ERROR token ends with a 4-byte line number. mssqlEnsureSkipBVarStrings throws this when fewer than 4 bytes remain before the token end, so the line number cannot be read and the token is incomplete relative to the TDS spec.

Source

Thrown at plugins/services/mssql_raw.go:379

	}
	_, _, 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 {
			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) {

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Re-run the login; a one-off truncation is usually network-related.
  2. Capture the raw packet and check whether the token's declared size matches the full TDS ERROR token layout.
  3. Compare server behavior against the TDS spec version your parser targets and pin the negotiated TDS version.
  4. Close the connection on this error; the remaining token stream cannot be trusted.
Defensive patterns

Strategy: validation

Validate before calling

if end-pos < 4 {
    return fmt.Errorf("ERROR token missing 4-byte line number (only %d bytes left)", end-pos)
}

Try / catch

if err := mssqlEnsureSkipBVarStrings(payload, pos, end); err != nil {
    return fmt.Errorf("dropping malformed server error: %w", err)
}

Prevention

When it happens

Trigger: Both BVarChar strings were consumed but pos+4 > end when attempting to skip the trailing 4-byte line-number field of an ERROR token.

Common situations: Token length was under-declared by the server (or middlebox truncated the token tail); fuzzer-crafted tokens; TDS version differences altering token layout.

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/1dc7c12e4e97780f. Report an issue: GitHub.