projectdiscovery/nuclei · warning

mysql handshake packet too short

Error message

mysql handshake packet too short

What it means

detectMySQLVersion mirrors fingerprintx's CheckInitialHandshakePacket and requires the whole greeting (4-byte header + payload) to be at least 35 bytes — enough for protocol version, server version string, connection id, salt part 1, and capability lower word. This error means the greeting is structurally too small to be a real MySQL handshake, so no version can be extracted.

Source

Thrown at pkg/js/libs/mysql/fingerprint.go:226

		return HandshakeInfo{}, err
	}

	info := HandshakeInfo{
		PacketType:      "handshake",
		ProtocolVersion: mysqlProtocolVersion10,
		Version:         version,
	}

	// Phase 2: best-effort enrichment. Failures here must not drop Version.
	enrichMySQLHandshake(&info, packet, versionEnd)
	return info, nil
}

// detectMySQLVersion mirrors fingerprintx CheckInitialHandshakePacket so we
// accept the same greetings and always surface the server version string.
func detectMySQLVersion(packet []byte) (string, int, error) {
	if len(packet) < 35 {
		return "", 0, fmt.Errorf("mysql handshake packet too short")
	}

	// fingerprintx treats bytes[0:4] as little-endian length (seq usually 0).
	// Use the real 3-byte MySQL length for bounds, but keep the same 25..4096 gate.
	length := mysqlPacketLength(packet)
	if length < 25 || length > 4096 {
		return "", 0, fmt.Errorf("mysql handshake packet length out of range")
	}
	if packet[4] != mysqlProtocolVersion10 {
		return "", 0, fmt.Errorf("unsupported mysql protocol version")
	}

	version, nullPos, err := readNullTerminatedASCIIString(packet, 5)
	if err != nil {
		return "", 0, err
	}
	// nullPos points at the NUL; fingerprintx filler is at nullPos+13.
	fillerPos := nullPos + 13

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Check what the port actually is (nmap -sV, nc) before running the mysql fingerprint
  2. Retry once — deadline truncation on slow links can clip the greeting
  3. If the target really is MySQL, verify with a real client (mysql CLI) that it completes a handshake
  4. Skip mysql-specific templates for hosts whose greeting is under 35 bytes and use generic detection
Defensive patterns

Strategy: try-catch

Validate before calling

// cheap pre-check: only fingerprint ports plausibly running mysql
const likely = [3306, 33060, 3307].includes(port) || customDbPorts.has(port);

Try / catch

try { const info = mysql.FingerprintMySQL(host, port); }
catch (e) { if (String(e).includes('mysql handshake packet too short')) log('short greeting, likely not mysql: ' + host); else throw e; }

Prevention

When it happens

Trigger: mysql.FingerprintMySQL(host, port) against a port whose greeting is a short non-MySQL banner (e.g. a line of text under 35 bytes), or a MySQL variant emitting an unusually minimal handshake.

Common situations: Fingerprinting arbitrary open ports where banners like '220 ftp ready' or single-line service mottos arrive; containers/toy servers implementing a MySQL-like subset; truncated reads on slow links hitting the 5s deadline.

Understand the failure class

Related errors


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