{"record":{"id":"62680a68d0605033","repo":"projectdiscovery/nuclei","slug":"w-v","errorCode":null,"errorMessage":"%w: %v","messagePattern":"%w: %v","errorType":"exception","errorClass":"errNotMssql","httpStatus":null,"severity":"warning","filePath":"pkg/js/libs/mssql/fingerprint.go","lineNumber":149,"sourceCode":"\theader := make([]byte, 8)\n\tif _, err := io.ReadFull(conn, header); err != nil {\n\t\treturn info, err\n\t}\n\tpacketLen := int(binary.BigEndian.Uint16(header[2:4]))\n\tif packetLen < 8 {\n\t\treturn info, fmt.Errorf(\"%w: invalid TDS packet length %d\", errNotMssql, packetLen)\n\t}\n\tbody := make([]byte, packetLen-8)\n\tif packetLen > 8 {\n\t\tif _, err := io.ReadFull(conn, body); err != nil {\n\t\t\treturn info, err\n\t\t}\n\t}\n\tresponse := append(header, body...)\n\n\tparsed, err := parsePreloginResponse(response)\n\tif err != nil {\n\t\treturn info, fmt.Errorf(\"%w: %v\", errNotMssql, err)\n\t}\n\tinfo.Version = parsed.Version\n\tinfo.MajorVersion = parsed.MajorVersion\n\tinfo.MinorVersion = parsed.MinorVersion\n\tinfo.BuildNumber = parsed.BuildNumber\n\tinfo.Encryption = parsed.Encryption\n\tinfo.EncryptionMode = parsed.EncryptionMode\n\tinfo.Mars = parsed.Mars\n\tinfo.InstanceMatches = parsed.InstanceMatches\n\tinfo.TLS = parsed.Encryption == encryptOn || parsed.Encryption == encryptReq\n\tinfo.Raw = hex.EncodeToString(response)\n\tif ip := net.ParseIP(host); ip != nil {\n\t\tinfo.IP = ip.String()\n\t}\n\treturn info, nil\n}\n\ntype preloginData struct {","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/js/libs/mssql/fingerprint.go#L131-L167","documentation":"Returned by mssql.FingerprintMssql when parsePreloginResponse rejects the assembled packet, wrapping the specific parse failure (bad type byte, bad status byte, length mismatch, malformed option tokens) with the errNotMssql sentinel. Semantically identical to the raw length check: the service answered but the reply is not a valid MSSQL pre-login response, so the target is presumed not MSSQL.","triggerScenarios":"The reply's first bytes are a TLS ServerHello / alert (byte 0x16/0x15) instead of a TDS tabular-result packet; an HTTP error page on the port; a half-broken proxy answer that passes the >=8 length check but fails deeper structure validation.","commonSituations":"Probing ports behind load balancers or TLS-terminating proxies; servers that force encryption from the first byte; any non-MSSQL service that happens to send 8+ bytes whose length field looks plausible.","solutions":["Handle it as 'not MSSQL' and move on, or switch to mssql.IsMssql for a boolean result","Confirm you are hitting the real SQL TCP port, not a TLS frontend (try the TLS-port variant or check for a 0x16 first byte)","Log the raw hex (info.Raw on success paths) while debugging to see what the service actually sent"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const info = mssql.FingerprintMssql(host, port);\n} catch (e) {\n  if (String(e).includes('not a mssql service')) return; // classify as non-MSSQL\n  throw e; // real network errors still propagate\n}","preventionTips":["Filter on the errNotMssql message to separate 'not MSSQL' from transport errors","Prefer IsMssql for pure detection flows","When MSSQL is expected, check for a TLS-first listener (0x16 first byte) before probing"],"tags":["mssql","protocol","tds","fingerprinting","service-detection"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}