projectdiscovery/nuclei · warning

invalid mysql packet length %d

Error message

invalid mysql packet length %d

What it means

MySQL packets start with a 3-byte little-endian payload length; recvMySQLPacket rejects lengths of 0 and anything above 16 MiB (the protocol's 16MB max packet, enforced as 16*1024*1024). This error means the length field decoded to 0 or >16MiB, which a real MySQL/MariaDB server never sends for its initial greeting — the stream is not MySQL or is corrupted.

Source

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

		return HandshakeInfo{}, err
	}
	if len(raw) == 0 {
		return HandshakeInfo{}, fmt.Errorf("empty mysql greeting")
	}
	return parseMySQLGreeting(raw)
}

func recvMySQLPacket(conn net.Conn, timeout time.Duration) ([]byte, error) {
	if err := conn.SetReadDeadline(time.Now().Add(timeout)); err != nil {
		return nil, err
	}
	header := make([]byte, 4)
	if _, err := io.ReadFull(conn, header); err != nil {
		return nil, err
	}
	length := int(uint32(header[0]) | uint32(header[1])<<8 | uint32(header[2])<<16)
	if length <= 0 || length > 16*1024*1024 {
		return nil, fmt.Errorf("invalid mysql packet length %d", length)
	}
	payload := make([]byte, length)
	if _, err := io.ReadFull(conn, payload); err != nil {
		return nil, err
	}
	out := make([]byte, 0, 4+length)
	out = append(out, header...)
	out = append(out, payload...)
	return out, nil
}

func parseMySQLGreeting(packet []byte) (HandshakeInfo, error) {
	if len(packet) < 5 {
		return HandshakeInfo{}, fmt.Errorf("mysql packet too short")
	}
	if packet[4] == mysqlErrorHeader {
		return parseMySQLErrorPacket(packet)
	}

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Verify the service first: nmap -sV -p <port> or a plain nc to inspect the banner
  2. Confirm you are hitting the real MySQL port (default 3306) and not a proxy/tunnel endpoint
  3. Use mysql.IsMySQL if available, or guard FingerprintMySQL with a try/catch and fall back to generic detection
  4. If TLS-wrapped MySQL, fingerprint will see TLS bytes — use an SSL probe instead
Defensive patterns

Strategy: try-catch

Validate before calling

// probe the banner cheaply before fingerprinting
// (nuclei network template reading first bytes) — if it does not look binary/MySQL, skip mysql.FingerprintMySQL

Try / catch

try { const info = mysql.FingerprintMySQL(host, port); }
catch (e) { if (String(e).includes('invalid mysql packet length')) log('non-mysql service on ' + host + ':' + port); else throw e; }

Prevention

When it happens

Trigger: mysql.FingerprintMySQL(host, port) (or any flow through fingerprintConn) against a port speaking another protocol whose first three bytes decode to an extreme value — e.g. HTTP 'HTT' = 0x545448, SSH banners, or binary RPC protocols; also possible with middleboxes that inject bytes.

Common situations: Running MySQL fingerprint templates against whole port ranges; services behind CDN/proxies; misconfigured port mappings (e.g. MySQL expected on 3306 but something else listens); TLS-only endpoints sending 0x16 0x03 ... which can decode to a large length.

Related errors


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