projectdiscovery/nuclei · warning

response too short for TDS header

Error message

response too short for TDS header

What it means

Returned by parsePreloginResponse (and surfaced via FingerprintMssql wrapped in errNotMssql) when the response buffer is under 8 bytes, too short to contain a TDS header. In the live probe path this is largely defensive: fingerprintMssql already reads exactly 8 header bytes with io.ReadFull (a short reply fails earlier with io.ErrUnexpectedEOF), so this branch fires mainly for direct/internal callers passing truncated buffers.

Source

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

	}
	return info, nil
}

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
	}

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Feed the parser only complete responses: read the full 8-byte header (plus body per the length field) before parsing
  2. In tests, use a realistic pre-login packet (>= 8 bytes starting with 04 01) as fixture
  3. At the JS/template level, prefer FingerprintMssql/IsMssql which handle framing for you
Defensive patterns

Strategy: fallback

Try / catch

try {
  const info = mssql.FingerprintMssql(host, port);
} catch (e) {
  if (String(e).includes('not a mssql service')) return; // short/malformed TDS => skip
  throw e;
}

Prevention

When it happens

Trigger: Unit tests or custom Go code calling parsePreloginResponse with a 0-7 byte slice; theoretically a zero-length body when packetLen==8 (header-only) still passes since len==8. Real short replies from the network surface as io errors before this check.

Common situations: Contributors writing tests for the mssql parser with hand-crafted short inputs; refactors that bypass the ReadFull header step.

Related errors


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