projectdiscovery/nuclei · warning

unexpected TDS type 0x%02x

Error message

unexpected TDS type 0x%02x

What it means

Returned by parsePreloginResponse when the first response byte is not 0x04 (TDSTYPE_TABULARRESULT, the packet type a pre-login reply must use), wrapped into errNotMssql by FingerprintMssql. A TDS pre-login response starts 04 01; any other leading byte means the reply is a different packet type or a different protocol entirely.

Source

Thrown at pkg/js/libs/mssql/fingerprint.go:184

type preloginData struct {
	Version         string
	MajorVersion    int
	MinorVersion    int
	BuildNumber     int
	Encryption      int
	EncryptionMode  string
	Mars            bool
	InstanceMatches bool
}

func parsePreloginResponse(response []byte) (preloginData, error) {
	var out preloginData
	if len(response) < 8 {
		return out, fmt.Errorf("response too short for TDS header")
	}
	if response[0] != tdsTypeTabularResult {
		return out, fmt.Errorf("unexpected TDS type 0x%02x", response[0])
	}
	if response[1] != tdsStatusEOM {
		return out, fmt.Errorf("unexpected TDS status 0x%02x", response[1])
	}
	packetLength := int(binary.BigEndian.Uint16(response[2:4]))
	if len(response) != packetLength {
		return out, fmt.Errorf("packet length mismatch: header=%d body=%d", packetLength, len(response))
	}

	type optionToken struct {
		token  byte
		offset uint16
		length uint16
		data   []byte
	}

	position := 8
	var tokens []optionToken

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Interpret as 'not MSSQL (or TLS-wrapped)': fall back to mssql.IsMssql or skip the target
  2. If MSSQL is expected, verify the port is the direct SQL TCP port and not a TLS frontend; try the TLS dial variant if available
  3. Compare the first byte heuristics in the template (0x16 => TLS, 0x04 => TDS) before fingerprinting
Defensive patterns

Strategy: fallback

Try / catch

try {
  const info = mssql.FingerprintMssql(host, port);
} catch (e) {
  if (String(e).includes('not a mssql service')) return; // wrong protocol on this port
  throw e;
}

Prevention

When it happens

Trigger: Server answers with a TLS record (first byte 0x16 handshake / 0x15 alert) because encryption is forced from byte zero; an HTTP response (letter bytes) on the probed port; any non-MSSQL banner whose length field happened to be >= 8.

Common situations: Probing a port in front of a TLS terminator; SQL Server configured with force encryption behind some proxies; scanning mixed services on a port range and hitting SSH/HTTP first bytes.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/028ce86df6e08dd7. Report an issue: GitHub.