projectdiscovery/nuclei · warning

mysql handshake filler byte is not zero

Error message

mysql handshake filler byte is not zero

What it means

Thrown by the MySQL fingerprint parser while decoding the server's initial handshake (greeting) packet. After reading the NUL-terminated server version string starting at offset 5, the parser expects the fingerprintx packet layout: 4-byte thread id, 8-byte auth-plugin-data part 1, and then a filler byte at nullPos+13 that must be 0x00. A non-zero byte at that position means the greeting does not match the MySQL wire format, so the fingerprint is rejected. The error propagates out of mysql.IsMySQL / FingerprintMySQL (and thus Connect / ExecuteQuery, which call IsMySQL first).

Source

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

	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) {
	length := mysqlPacketLength(packet)
	if length+4 > len(packet) {
		length = len(packet) - 4
	}
	if length <= 0 {
		return
	}
	payload := packet[4 : 4+length]
	// versionEnd is absolute index of first byte after version NUL in packet.
	pos := versionEnd - 4
	if pos < 0 || pos > len(payload) {
		return
	}

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Confirm the target is really MySQL on that port (e.g. `mysql -h host -P port -u x` or an nmap mysql probe) and fix the port in the template
  2. Treat this error as 'not MySQL' in the template logic and continue scanning other ports — it is an expected probe outcome, not a bug
  3. If the target should be MySQL, capture the raw greeting (hexdump the first packet) and verify byte 0 is protocol version 0x0a and a 0x00 filler exists 13 bytes after the version's NUL terminator
  4. Check for transparent proxies / IPS devices between scanner and target that may rewrite the banner

Example fix

// before
const info = mysql.FingerprintMySQL('acme.com', 3306);
log(to_json(info)); // error kills the script on non-mysql targets

// after
try {
  const info = mysql.FingerprintMySQL('acme.com', 3306);
  log(to_json(info));
} catch (e) {
  log('not a mysql service: ' + e); // keep scanning
}
Defensive patterns

Strategy: try-catch

Validate before calling

// cheap pre-check: read the greeting and verify MySQL protocol version 0x0a
const conn = net.Open('tcp', host + ':' + port);
const banner = conn.Recv(128);
conn.Close();
if (banner.charCodeAt(4) !== 0x0a) { log('not mysql, skip'); }

Type guard

function looksLikeMysqlGreeting(b) {
  return b && b.length > 5 && b.charCodeAt(4) === 0x0a && b.indexOf('\u0000', 5) !== -1;
}

Try / catch

try {
  const info = mysql.FingerprintMySQL(host, port);
} catch (e) {
  // any fingerprint parse error === treat as non-mysql, continue template
  log('fingerprint rejected: ' + e);
}

Prevention

When it happens

Trigger: Calling mysql.IsMySQL, mysql.FingerprintMySQL, mysql.Connect or mysql.ExecuteQuery against a TCP port where something answers with bytes but is not a real MySQL server (e.g. another database, a custom TCP service, or a proxy that rewrites the banner). Concretely: the version string parses fine, but packet[nullPos+13] != 0x00.

Common situations: Scanning a port list where 3306 is actually served by another protocol; MySQL-compatible forks or intermediaries that alter the greeting header layout; TLS-wrapped MySQL ports probed in plaintext producing a parseable-looking prefix but garbage filler byte; version-detection templates run against arbitrary open ports.

Understand the failure class

Related errors


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