{"record":{"id":"1dc7c12e4e97780f","repo":"shadow1ng/fscan","slug":"mssql-truncated-error-line-number","errorCode":null,"errorMessage":"mssql: truncated error line number","messagePattern":"mssql: truncated error line number","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/mssql_raw.go","lineNumber":379,"sourceCode":"\t}\n\t_, _, err := mssqlReadUSVarChar(payload, pos+8)\n\treturn end, err\n}\n\nfunc mssqlEnsureSkipBVarStrings(payload []byte, pos, end int) error {\n\tfor i := 0; i < 2; i++ {\n\t\tif pos >= end {\n\t\t\treturn fmt.Errorf(\"mssql: truncated string in error token\")\n\t\t}\n\t\tlength := int(payload[pos]) * 2\n\t\tpos++\n\t\tif pos+length > end {\n\t\t\treturn fmt.Errorf(\"mssql: invalid string in error token\")\n\t\t}\n\t\tpos += length\n\t}\n\tif pos+4 > end {\n\t\treturn fmt.Errorf(\"mssql: truncated error line number\")\n\t}\n\treturn nil\n}\n\nfunc mssqlSkipLen16(payload []byte, pos int) (int, error) {\n\tif pos+2 > len(payload) {\n\t\treturn pos, fmt.Errorf(\"mssql: truncated token\")\n\t}\n\tsize := int(binary.LittleEndian.Uint16(payload[pos : pos+2]))\n\tnext := pos + 2 + size\n\tif next > len(payload) {\n\t\treturn pos, fmt.Errorf(\"mssql: invalid token size\")\n\t}\n\treturn next, nil\n}\n\nfunc mssqlReadUSVarChar(payload []byte, pos int) (string, int, error) {\n\tif pos+2 > len(payload) {","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/mssql_raw.go#L361-L397","documentation":"After the two BVarChar strings, a TDS ERROR token ends with a 4-byte line number. mssqlEnsureSkipBVarStrings throws this when fewer than 4 bytes remain before the token end, so the line number cannot be read and the token is incomplete relative to the TDS spec.","triggerScenarios":"Both BVarChar strings were consumed but pos+4 > end when attempting to skip the trailing 4-byte line-number field of an ERROR token.","commonSituations":"Token length was under-declared by the server (or middlebox truncated the token tail); fuzzer-crafted tokens; TDS version differences altering token layout.","solutions":["Re-run the login; a one-off truncation is usually network-related.","Capture the raw packet and check whether the token's declared size matches the full TDS ERROR token layout.","Compare server behavior against the TDS spec version your parser targets and pin the negotiated TDS version.","Close the connection on this error; the remaining token stream cannot be trusted."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if end-pos < 4 {\n    return fmt.Errorf(\"ERROR token missing 4-byte line number (only %d bytes left)\", end-pos)\n}","typeGuard":null,"tryCatchPattern":"if err := mssqlEnsureSkipBVarStrings(payload, pos, end); err != nil {\n    return fmt.Errorf(\"dropping malformed server error: %w\", err)\n}","preventionTips":["Treat the line-number field as mandatory when validating token size.","Prefer failing the login over resuming at a guessed offset.","Capture raw packets when the error is reproducible to identify the truncating hop.","Compare token layout against the official TDS specification for your server version."],"tags":["mssql","tds-protocol","malformed-packet","wire-parsing"],"backgroundTag":"unexpected-api-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"}