shadow1ng/fscan · error

mssql: truncated prelogin option

Error message

mssql: truncated prelogin option

What it means

A prelogin option entry was started but fewer than 5 bytes remained in the payload, so the offset+length pair could not be read. Each non-terminator entry needs exactly 5 bytes: token (1) + offset (2) + length (2).

Source

Thrown at plugins/services/mssql_raw.go:181

	}
	if _, ok := fields[tdsPreloginEncryption]; !ok {
		return fmt.Errorf("mssql: prelogin response missing encryption field")
	}
	return nil
}

func mssqlParsePreloginFields(payload []byte) (map[byte][]byte, error) {
	fields := make(map[byte][]byte)
	for pos := 0; ; pos += 5 {
		if pos >= len(payload) {
			return nil, fmt.Errorf("mssql: invalid prelogin option table")
		}
		token := payload[pos]
		if token == tdsPreloginTerminator {
			return fields, nil
		}
		if pos+5 > len(payload) {
			return nil, fmt.Errorf("mssql: truncated prelogin option")
		}
		offset := int(binary.BigEndian.Uint16(payload[pos+1 : pos+3]))
		length := int(binary.BigEndian.Uint16(payload[pos+3 : pos+5]))
		if offset < 0 || length < 0 || offset+length > len(payload) {
			return nil, fmt.Errorf("mssql: invalid prelogin option bounds")
		}
		fields[token] = payload[offset : offset+length]
	}
}

func mssqlSendLogin7(w io.Writer, host, username, password string) error {
	values := []struct {
		text     string
		password bool
	}{
		{"", false},
		{username, false},
		{password, true},

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Capture the full packet and check whether the server truly sent a truncated table or a middlebox dropped bytes.
  2. Retry against a known-good SQL Server to isolate server vs network.
  3. If writing the peer side, ensure the option table is emitted fully before the value data.
  4. Treat as protocol corruption: reconnect and log the raw payload for diagnosis.
Defensive patterns

Strategy: try-catch

Try / catch

_, err := mssqlRawLogin(ctx, host, port, user, pass, timeout)
if err != nil && strings.Contains(err.Error(), "truncated prelogin option") {
    // packet ended mid-option: retry or capture traffic
}

Prevention

When it happens

Trigger: mssqlParsePreloginFields finds a non-0xFF token at pos but pos+5 > len(payload) — e.g. 1–4 trailing bytes after the last complete entry.

Common situations: Packet truncation by network devices; partial reads being concatenated incorrectly; hand-crafted or fuzzed TDS responses.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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