shadow1ng/fscan · error
mssql: invalid packet size
Error message
mssql: invalid packet size
What it means
Each TDS packet's 8-byte header stores the total packet size (header + payload) as a 16-bit big-endian integer. A size below 8 is impossible — the header alone is 8 bytes — so mssqlReadMessage rejects the packet as malformed rather than computing a negative chunk length.
Source
Thrown at plugins/services/mssql_raw.go:437
return err
}
func mssqlReadMessage(r io.Reader) (byte, []byte, error) {
var packetType byte
var payload []byte
for {
header := make([]byte, 8)
if _, err := io.ReadFull(r, header); err != nil {
return 0, nil, err
}
if packetType == 0 {
packetType = header[0]
} else if packetType != header[0] {
return 0, nil, fmt.Errorf("mssql: packet type changed in message")
}
size := int(binary.BigEndian.Uint16(header[2:4]))
if size < 8 {
return 0, nil, fmt.Errorf("mssql: invalid packet size")
}
chunk := make([]byte, size-8)
if _, err := io.ReadFull(r, chunk); err != nil {
return 0, nil, err
}
if len(payload)+len(chunk) > maxTDSMessageSize {
return 0, nil, fmt.Errorf("mssql: message too large")
}
payload = append(payload, chunk...)
if header[1]&tdsStatusEOM != 0 {
return packetType, payload, nil
}
}
}
func mssqlUCS2(s string) []byte {
runes := utf16.Encode([]rune(s))
out := make([]byte, len(runes)*2)View on GitHub (pinned to 95cc12e753)
Solutions
- Verify the target port actually hosts a SQL Server TDS endpoint.
- Reset the connection; the framing is invalid and cannot be resynchronized mid-stream.
- Log the raw header bytes (type, status, size) to diagnose whether it is TDS at all.
- Bypass any intermediate proxy suspected of corrupting the stream.
Defensive patterns
Strategy: try-catch
Try / catch
_, payload, err := mssqlReadMessage(conn)
if err != nil {
if strings.Contains(err.Error(), "invalid packet size") {
// header corrupted or not TDS: close and re-dial
conn.Close()
}
} Prevention
- Verify the service fingerprint on the port before speaking TDS.
- Log the raw 8-byte header when this occurs to aid diagnosis.
- Bypass middleboxes that may corrupt packet headers.
- Never retry mid-stream; always re-dial from scratch.
When it happens
Trigger: A packet header from a prelogin or login response stream declares a size < 8 bytes: corrupt stream, truncated/mangled header, or non-TDS data on the socket.
Common situations: Wrong service behind the port emitting binary junk; a broken proxy corrupting headers; fuzzers or honeypots sending zeroed/garbage size fields.
Related errors
- mssql: invalid us varchar size
- mssql: packet type changed in message
- mssql: login acknowledgement not received
- mssql: invalid prelogin response packet type %d
- mssql: empty prelogin response
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/20ab3f6d91b062cb.
Report an issue: GitHub.