{"record":{"id":"20ab3f6d91b062cb","repo":"shadow1ng/fscan","slug":"mssql-invalid-packet-size","errorCode":null,"errorMessage":"mssql: invalid packet size","messagePattern":"mssql: invalid packet size","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/mssql_raw.go","lineNumber":437,"sourceCode":"\treturn err\n}\n\nfunc mssqlReadMessage(r io.Reader) (byte, []byte, error) {\n\tvar packetType byte\n\tvar payload []byte\n\tfor {\n\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)","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/mssql_raw.go#L419-L455","documentation":"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.","triggerScenarios":"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.","commonSituations":"Wrong service behind the port emitting binary junk; a broken proxy corrupting headers; fuzzers or honeypots sending zeroed/garbage size fields.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, payload, err := mssqlReadMessage(conn)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid packet size\") {\n        // header corrupted or not TDS: close and re-dial\n        conn.Close()\n    }\n}","preventionTips":["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."],"tags":["mssql","tds","packet-header","malformed-input"],"backgroundTag":"unexpected-response-shape","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}