{"record":{"id":"20c53f3f83117ef8","repo":"shadow1ng/fscan","slug":"mssql-message-too-large","errorCode":null,"errorMessage":"mssql: message too large","messagePattern":"mssql: message too large","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/mssql_raw.go","lineNumber":444,"sourceCode":"\t\theader := make([]byte, 8)\n\t\tif _, err := io.ReadFull(r, header); err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tif packetType == 0 {\n\t\t\tpacketType = header[0]\n\t\t} else if packetType != header[0] {\n\t\t\treturn 0, nil, fmt.Errorf(\"mssql: packet type changed in message\")\n\t\t}\n\t\tsize := int(binary.BigEndian.Uint16(header[2:4]))\n\t\tif size < 8 {\n\t\t\treturn 0, nil, fmt.Errorf(\"mssql: invalid packet size\")\n\t\t}\n\t\tchunk := make([]byte, size-8)\n\t\tif _, err := io.ReadFull(r, chunk); err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tif len(payload)+len(chunk) > maxTDSMessageSize {\n\t\t\treturn 0, nil, fmt.Errorf(\"mssql: message too large\")\n\t\t}\n\t\tpayload = append(payload, chunk...)\n\t\tif header[1]&tdsStatusEOM != 0 {\n\t\t\treturn packetType, payload, nil\n\t\t}\n\t}\n}\n\nfunc mssqlUCS2(s string) []byte {\n\trunes := utf16.Encode([]rune(s))\n\tout := make([]byte, len(runes)*2)\n\tfor i, r := range runes {\n\t\tbinary.LittleEndian.PutUint16(out[i*2:], r)\n\t}\n\treturn out\n}\n\nfunc mssqlDecodeUCS2(data []byte) string {","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/mssql_raw.go#L426-L462","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, payload, err := mssqlReadMessage(conn)\nif err != nil {\n    if strings.Contains(err.Error(), \"message too large\") {\n        // one clean reconnect; if it recurs, blocklist the target\n        conn.Close()\n        return retryOnceOrBlocklist(target)\n    }\n}","preventionTips":["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."],"tags":["mssql","tds","message-size-limit","dos-protection"],"backgroundTag":"payload-too-large","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}