{"record":{"id":"45256d77efdbf2a7","repo":"projectdiscovery/nuclei","slug":"mysql-handshake-packet-too-short","errorCode":null,"errorMessage":"mysql handshake packet too short","messagePattern":"mysql handshake packet too short","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/js/libs/mysql/fingerprint.go","lineNumber":226,"sourceCode":"\t\treturn HandshakeInfo{}, err\n\t}\n\n\tinfo := HandshakeInfo{\n\t\tPacketType:      \"handshake\",\n\t\tProtocolVersion: mysqlProtocolVersion10,\n\t\tVersion:         version,\n\t}\n\n\t// Phase 2: best-effort enrichment. Failures here must not drop Version.\n\tenrichMySQLHandshake(&info, packet, versionEnd)\n\treturn info, nil\n}\n\n// detectMySQLVersion mirrors fingerprintx CheckInitialHandshakePacket so we\n// accept the same greetings and always surface the server version string.\nfunc detectMySQLVersion(packet []byte) (string, int, error) {\n\tif len(packet) < 35 {\n\t\treturn \"\", 0, fmt.Errorf(\"mysql handshake packet too short\")\n\t}\n\n\t// fingerprintx treats bytes[0:4] as little-endian length (seq usually 0).\n\t// Use the real 3-byte MySQL length for bounds, but keep the same 25..4096 gate.\n\tlength := mysqlPacketLength(packet)\n\tif length < 25 || length > 4096 {\n\t\treturn \"\", 0, fmt.Errorf(\"mysql handshake packet length out of range\")\n\t}\n\tif packet[4] != mysqlProtocolVersion10 {\n\t\treturn \"\", 0, fmt.Errorf(\"unsupported mysql protocol version\")\n\t}\n\n\tversion, nullPos, err := readNullTerminatedASCIIString(packet, 5)\n\tif err != nil {\n\t\treturn \"\", 0, err\n\t}\n\t// nullPos points at the NUL; fingerprintx filler is at nullPos+13.\n\tfillerPos := nullPos + 13","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/js/libs/mysql/fingerprint.go#L208-L244","documentation":"detectMySQLVersion mirrors fingerprintx's CheckInitialHandshakePacket and requires the whole greeting (4-byte header + payload) to be at least 35 bytes — enough for protocol version, server version string, connection id, salt part 1, and capability lower word. This error means the greeting is structurally too small to be a real MySQL handshake, so no version can be extracted.","triggerScenarios":"mysql.FingerprintMySQL(host, port) against a port whose greeting is a short non-MySQL banner (e.g. a line of text under 35 bytes), or a MySQL variant emitting an unusually minimal handshake.","commonSituations":"Fingerprinting arbitrary open ports where banners like '220 ftp ready' or single-line service mottos arrive; containers/toy servers implementing a MySQL-like subset; truncated reads on slow links hitting the 5s deadline.","solutions":["Check what the port actually is (nmap -sV, nc) before running the mysql fingerprint","Retry once — deadline truncation on slow links can clip the greeting","If the target really is MySQL, verify with a real client (mysql CLI) that it completes a handshake","Skip mysql-specific templates for hosts whose greeting is under 35 bytes and use generic detection"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// cheap pre-check: only fingerprint ports plausibly running mysql\nconst likely = [3306, 33060, 3307].includes(port) || customDbPorts.has(port);","typeGuard":null,"tryCatchPattern":"try { const info = mysql.FingerprintMySQL(host, port); }\ncatch (e) { if (String(e).includes('mysql handshake packet too short')) log('short greeting, likely not mysql: ' + host); else throw e; }","preventionTips":["Prefer service-validated inputs over raw port sweeps for mysql templates","Retry once on slow links — the 5s deadline can clip greetings","Wrap every FingerprintMySQL call in try/catch and continue the scan"],"tags":["mysql","protocol-parsing","fingerprint","truncated-response","network","go"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}