{"record":{"id":"b26dc5aa1a0cd40e","repo":"projectdiscovery/nuclei","slug":"mysql-packet-too-short","errorCode":null,"errorMessage":"mysql packet too short","messagePattern":"mysql packet too short","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/js/libs/mysql/fingerprint.go","lineNumber":166,"sourceCode":"\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}\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\")","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/js/libs/mysql/fingerprint.go#L148-L184","documentation":"parseMySQLGreeting needs at least 5 bytes: the 4-byte header plus the payload's first byte, which distinguishes an error packet (0xff) from a handshake. This error means fewer than 5 bytes were supplied, so even the packet type cannot be read. On the live path recvMySQLPacket enforces length >= 1, so this fires from direct parser use (tests, fuzzing) or a future caller bypassing the read gate.","triggerScenarios":"Calling parseMySQLGreeting (or the JS FingerprintMySQL flow) with a buffer under 5 bytes — truncated captures fed into Go tests, fuzz corpora, or a connection that closed after delivering a partial header.","commonSituations":"Go unit tests with short fixtures; pcap-derived payloads that were cut; connections closed mid-read by aggressive firewalls so only a few bytes arrived.","solutions":["On the live path, treat as 'connection closed early / not MySQL' and fall back to banner detection","In Go tests, ensure fixtures include the 4-byte header plus at least 1 payload byte","Capture the exchange with tcpdump to see exactly how many bytes the server sent","Retry once to rule out transient truncation before classifying the port as non-MySQL"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { const info = mysql.FingerprintMySQL(host, port); }\ncatch (e) { if (String(e).includes('mysql packet too short')) log('greeting truncated from ' + host); else throw e; }","preventionTips":["In Go tests, give parseMySQLGreeting fixtures of at least 5 bytes (header + 1 payload byte)","On the wire path, treat as a closed-early connection and fall back to banner detection"],"tags":["mysql","protocol-parsing","fingerprint","truncated-response","go"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}