{"record":{"id":"0408ab62f9fdf974","repo":"projectdiscovery/nuclei","slug":"invalid-mysql-packet-length-d","errorCode":null,"errorMessage":"invalid mysql packet length %d","messagePattern":"invalid mysql packet length (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/js/libs/mysql/fingerprint.go","lineNumber":152,"sourceCode":"\t\treturn HandshakeInfo{}, err\n\t}\n\tif len(raw) == 0 {\n\t\treturn HandshakeInfo{}, fmt.Errorf(\"empty mysql greeting\")\n\t}\n\treturn parseMySQLGreeting(raw)\n}\n\nfunc recvMySQLPacket(conn net.Conn, timeout time.Duration) ([]byte, error) {\n\tif err := conn.SetReadDeadline(time.Now().Add(timeout)); err != nil {\n\t\treturn nil, err\n\t}\n\theader := make([]byte, 4)\n\tif _, err := io.ReadFull(conn, header); err != nil {\n\t\treturn nil, err\n\t}\n\tlength := int(uint32(header[0]) | uint32(header[1])<<8 | uint32(header[2])<<16)\n\tif length <= 0 || length > 16*1024*1024 {\n\t\treturn nil, fmt.Errorf(\"invalid mysql packet length %d\", length)\n\t}\n\tpayload := make([]byte, length)\n\tif _, err := io.ReadFull(conn, payload); err != nil {\n\t\treturn nil, err\n\t}\n\tout := make([]byte, 0, 4+length)\n\tout = append(out, header...)\n\tout = append(out, payload...)\n\treturn out, nil\n}\n\nfunc parseMySQLGreeting(packet []byte) (HandshakeInfo, error) {\n\tif len(packet) < 5 {\n\t\treturn HandshakeInfo{}, fmt.Errorf(\"mysql packet too short\")\n\t}\n\tif packet[4] == mysqlErrorHeader {\n\t\treturn parseMySQLErrorPacket(packet)\n\t}","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/js/libs/mysql/fingerprint.go#L134-L170","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the service first: nmap -sV -p <port> or a plain nc to inspect the banner","Confirm you are hitting the real MySQL port (default 3306) and not a proxy/tunnel endpoint","Use mysql.IsMySQL if available, or guard FingerprintMySQL with a try/catch and fall back to generic detection","If TLS-wrapped MySQL, fingerprint will see TLS bytes — use an SSL probe instead"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// probe the banner cheaply before fingerprinting\n// (nuclei network template reading first bytes) — if it does not look binary/MySQL, skip mysql.FingerprintMySQL","typeGuard":null,"tryCatchPattern":"try { const info = mysql.FingerprintMySQL(host, port); }\ncatch (e) { if (String(e).includes('invalid mysql packet length')) log('non-mysql service on ' + host + ':' + port); else throw e; }","preventionTips":["Expect this on any non-MySQL protocol sharing the port — always try/catch FingerprintMySQL","Run service discovery (nmap -sV) before mysql templates","For TLS-wrapped MySQL, use TLS probes; the plaintext fingerprint cannot succeed"],"tags":["mysql","protocol-parsing","fingerprint","packet-length","network","go"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}