{"record":{"id":"181187d583a3d2d7","repo":"projectdiscovery/nuclei","slug":"mysql-error-packet-has-invalid-header","errorCode":null,"errorMessage":"mysql error packet has invalid header","messagePattern":"mysql error packet has invalid header","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"pkg/js/libs/mysql/fingerprint.go","lineNumber":184,"sourceCode":"\t\treturn HandshakeInfo{}, fmt.Errorf(\"mysql packet too short\")\n\t}\n\tif packet[4] == mysqlErrorHeader {\n\t\treturn parseMySQLErrorPacket(packet)\n\t}\n\treturn parseMySQLHandshakePacket(packet)\n}\n\nfunc parseMySQLErrorPacket(packet []byte) (HandshakeInfo, error) {\n\t// Stay compatible with fingerprintx error detection: minimum size and 0xff header.\n\tif len(packet) < 8 {\n\t\treturn HandshakeInfo{}, fmt.Errorf(\"mysql error packet too short\")\n\t}\n\tlength := mysqlPacketLength(packet)\n\tif length < 3 || length+4 > len(packet) {\n\t\treturn HandshakeInfo{}, fmt.Errorf(\"mysql error packet truncated\")\n\t}\n\tif packet[4] != mysqlErrorHeader {\n\t\treturn HandshakeInfo{}, fmt.Errorf(\"mysql error packet has invalid header\")\n\t}\n\n\tinfo := HandshakeInfo{\n\t\tPacketType: \"error\",\n\t\tErrorCode:  int(binary.LittleEndian.Uint16(packet[5:7])),\n\t}\n\tmsgStart := 7\n\t// Protocol 4.1 error packets may include '#' + 5-byte SQLSTATE.\n\tif 4+length > 8 && packet[7] == '#' && 4+length >= 13 {\n\t\tmsgStart = 13\n\t}\n\tif msgStart < 4+length {\n\t\tinfo.ErrorMessage = readPrintableASCII(packet[msgStart : 4+length])\n\t}\n\treturn info, nil\n}\n\nfunc parseMySQLHandshakePacket(packet []byte) (HandshakeInfo, error) {","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/js/libs/mysql/fingerprint.go#L166-L202","documentation":"After routing on packet[4] == 0xff, parseMySQLErrorPacket re-validates that header byte as an internal invariant. Because the only caller (parseMySQLGreeting) enters this function precisely when packet[4] is 0xff, this branch is unreachable defensive code guarding against future callers passing non-error packets. Encountering it implies the parser was invoked directly with a handshake packet.","triggerScenarios":"Go code or tests calling parseMySQLErrorPacket directly with a packet whose 5th byte is not 0xff; not reachable through the public mysql.FingerprintMySQL flow.","commonSituations":"Unit tests exercising the error-packet parser in isolation; refactors that reroute packets to the wrong parse function.","solutions":["If writing Go tests, only feed packets whose byte 4 is 0xff to this function","Route through parseMySQLGreeting so the 0xff dispatch happens automatically","No action needed on the live path — prefer the public FingerprintMySQL API"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Go: only route error packets to the error parser\nfunc isErrorPacket(p []byte) bool { return len(p) >= 5 && p[4] == 0xff }","tryCatchPattern":null,"preventionTips":["Route packets through parseMySQLGreeting instead of calling parseMySQLErrorPacket directly","Check byte 4 == 0xff before invoking the error parser in tests"],"tags":["mysql","protocol-parsing","fingerprint","defensive-check","go"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}