shadow1ng/fscan · error
mssql: message too large
Error message
mssql: message too large
What it means
A single TDS message may span many packets, so mssqlReadMessage enforces a maximum accumulated payload size (maxTDSMessageSize) while concatenating chunks. If adding the next chunk would exceed that limit, the read aborts with this error to prevent unbounded memory growth from a hostile or broken peer.
Source
Thrown at plugins/services/mssql_raw.go:444
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)
for i, r := range runes {
binary.LittleEndian.PutUint16(out[i*2:], r)
}
return out
}
func mssqlDecodeUCS2(data []byte) string {View on GitHub (pinned to 95cc12e753)
Solutions
- Check the peer's EOM-bit handling: a legitimate server terminates every message; non-termination suggests a fake server — blocklist the target.
- Keep the limit in place (DoS protection); do not raise maxTDSMessageSize for untrusted hosts.
- Reset the connection and retry once in case of transient corruption.
- If you control the server side, fix it to set the EOM status bit on the final packet.
Defensive patterns
Strategy: retry
Try / catch
_, payload, err := mssqlReadMessage(conn)
if err != nil {
if strings.Contains(err.Error(), "message too large") {
// one clean reconnect; if it recurs, blocklist the target
conn.Close()
return retryOnceOrBlocklist(target)
}
} Prevention
- Keep maxTDSMessageSize as a hard cap against hostile servers.
- Blocklist peers whose messages never terminate with EOM.
- Set connection deadlines so endless streams cannot stall the scanner.
- Fingerprint fake TDS servers (honeypots) and skip them.
When it happens
Trigger: A prelogin/login response that keeps sending continuation packets (EOM bit unset) until accumulated payload exceeds maxTDSMessageSize — e.g. a server (or fake server) streaming endless non-terminating packets.
Common situations: Malicious TDS honeypots or fuzz servers never setting the EOM bit; a buggy server sending very large prelogin responses; a parser bug causing EOM detection to miss termination.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- mssql: login acknowledgement not received
- mssql: invalid prelogin response packet type %d
- mssql: empty prelogin response
- mssql: prelogin response missing encryption field
- mssql: invalid prelogin option table
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/20c53f3f83117ef8.
Report an issue: GitHub.