projectdiscovery/nuclei · warning
unsupported mysql protocol version
Error message
unsupported mysql protocol version
What it means
The parser only accepts protocol version 10 (0x0a) — the handshake protocol spoken by MySQL 3.21+ through 8.x and MariaDB. This error means payload byte 0 (packet[4]) held a different value: an older protocol (9), a pre-handshake AUTH switch or ERR-adjacent frame, or simply a non-MySQL stream that passed the length gates. fingerprintx applies the identical check, so greetings it rejects are rejected here too.
Source
Thrown at pkg/js/libs/mysql/fingerprint.go:236
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
if fillerPos >= len(packet) {
return "", 0, fmt.Errorf("mysql handshake missing filler byte")
}
if packet[fillerPos] != 0x00 {
return "", 0, fmt.Errorf("mysql handshake filler byte is not zero")
}
return version, nullPos + 1, nil
}
func enrichMySQLHandshake(info *HandshakeInfo, packet []byte, versionEnd int) {View on GitHub (pinned to 265b3a3dec)
Solutions
- Read the raw greeting (nc host 3306 | xxd) and check the 5th byte is 0a
- Confirm the server is stock MySQL/MariaDB with the mysql CLI client
- Treat the failure as a negative detection and use generic probes
- Ensure captures/fixtures include the full packet from the first length byte
Defensive patterns
Strategy: try-catch
Validate before calling
const likely = [3306, 33060, 3307].includes(port) || customDbPorts.has(port); if (!likely) return;
Try / catch
try { const info = mysql.FingerprintMySQL(host, port); }
catch (e) { if (String(e).includes('unsupported mysql protocol version')) log('not protocol-10 mysql: ' + host); else throw e; } Prevention
- Only protocol 10 (0x0a) greetings are accepted by design — treat others as non-MySQL
- Check the 5th byte of the raw banner when diagnosing
- For exotic forks, use authenticated queries after login instead of the greeting fingerprint
When it happens
Trigger: mysql.FingerprintMySQL against a service whose greeting passes length checks but starts with a byte other than 0x0a — e.g. protocol emulators, an alternate wire protocol on 3306, or a desynchronized stream where parsing begins mid-packet.
Common situations: Non-MySQL services on the MySQL port; MariaDB forks with experimental handshake tweaks; test fixtures with the version byte omitted; proxies shifting the byte stream.
Related errors
- empty mysql greeting
- invalid mysql packet length %d
- mysql handshake packet too short
- mysql handshake packet length out of range
- mysql handshake missing filler byte
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/c05a0b61bd8368c5.
Report an issue: GitHub.