{"id":"8af64579bab14a5d","repo":"go-sql-driver/mysql","slug":"unsupported-protocol-version-d-version-d-or-hig","errorCode":null,"errorMessage":"unsupported protocol version %d. Version %d or higher is required","messagePattern":"unsupported protocol version (.+?)\\. Version (.+?) or higher is required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packets.go","lineNumber":197,"sourceCode":"******************************************************************************/\n\n// Handshake Initialization Packet\n// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_handshake_v10.html\n// https://mariadb.com/kb/en/connection/#initial-handshake-packet\nfunc (mc *mysqlConn) readHandshakePacket() (data []byte, capabilities capabilityFlag, extendedCapabilities extendedCapabilityFlag, plugin string, err error) {\n\tdata, err = mc.readPacket()\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif data[0] == iERR {\n\t\terr = mc.handleErrorPacket(data)\n\t\treturn\n\t}\n\n\t// protocol version [1 byte]\n\tif data[0] < minProtocolVersion {\n\t\treturn nil, 0, 0, \"\", fmt.Errorf(\n\t\t\t\"unsupported protocol version %d. Version %d or higher is required\",\n\t\t\tdata[0],\n\t\t\tminProtocolVersion,\n\t\t)\n\t}\n\n\t// server version [null terminated string]\n\t// connection id [4 bytes]\n\tpos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 + 4\n\n\t// first part of the password cipher [8 bytes]\n\tauthData := data[pos : pos+8]\n\n\t// (filler) always 0x00 [1 byte]\n\tpos += 8 + 1\n\n\t// capability flags (lower 2 bytes) [2 bytes]\n\tcapabilities = capabilityFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/c426bd93799de0f0e094c8f0582872c529d0ed0a/packets.go#L179-L215","documentation":"Returned during the initial handshake (packets.go:197) when the server's first byte (protocol version) is less than 10 (minProtocolVersion, const.go:18). Protocol 10 is the current standard used by all modern MySQL/MariaDB servers, so a lower value means the endpoint is not a real MySQL server or is impossibly ancient. The driver cannot proceed.","triggerScenarios":"Dialing a TCP/unix address that is not a MySQL server (e.g. Redis on 6379, an HTTP/SSH port); a load balancer/proxy returning a non-MySQL banner; connecting to a pre-3.x MySQL server.","commonSituations":"Wrong host/port in the DSN; service discovery returns the wrong address; a sidecar (Envoy, HAProxy, ProxySQL) misroutes the connection; port-forward pointing at the wrong pod.","solutions":["Verify the DSN host/port point at a real MySQL/MariaDB server.","Confirm connectivity from the same host using the mysql CLI client.","Ensure no proxy/load-balancer is intercepting or misrouting the connection.","Confirm the backend is MySQL/MariaDB and not another database on the same port."],"exampleFix":"// before — wrong port (e.g. Redis)\nsql.Open(\"mysql\", \"user:pass@tcp(localhost:6379)/db\")\n\n// after\nsql.Open(\"mysql\", \"user:pass@tcp(localhost:3306)/db\")","handlingStrategy":"validation","validationCode":"// sanity-check that the endpoint speaks MySQL before opening the driver\nconn, err := net.DialTimeout(\"tcp\", addr, 5*time.Second)\nif err != nil { return err }\nbanner := make([]byte, 1)\n_, _ = conn.Read(banner)\nconn.Close()\nif banner[0] < 10 { return fmt.Errorf(\"endpoint %s is not a MySQL server\", addr) }","typeGuard":null,"tryCatchPattern":"if err := db.Ping(); err != nil {\n    if strings.Contains(err.Error(), \"unsupported protocol version\") {\n        // the endpoint is not MySQL; verify host/port and proxies\n    }\n}","preventionTips":["Validate the DSN host/port before deploying.","Confirm the endpoint with the mysql CLI from the same host.","Ensure proxies forward to the correct MySQL backend port."],"tags":["connection","handshake","network","configuration"],"analyzedSha":"c426bd93799de0f0e094c8f0582872c529d0ed0a","analyzedAt":"2026-08-04T21:52:59.219Z","schemaVersion":2}