go-sql-driver/mysql · critical
unsupported protocol version %d. Version %d or higher is req
Error message
unsupported protocol version %d. Version %d or higher is required
What it means
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.
Source
Thrown at packets.go:197
******************************************************************************/
// Handshake Initialization Packet
// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_handshake_v10.html
// https://mariadb.com/kb/en/connection/#initial-handshake-packet
func (mc *mysqlConn) readHandshakePacket() (data []byte, capabilities capabilityFlag, extendedCapabilities extendedCapabilityFlag, plugin string, err error) {
data, err = mc.readPacket()
if err != nil {
return
}
if data[0] == iERR {
err = mc.handleErrorPacket(data)
return
}
// protocol version [1 byte]
if data[0] < minProtocolVersion {
return nil, 0, 0, "", fmt.Errorf(
"unsupported protocol version %d. Version %d or higher is required",
data[0],
minProtocolVersion,
)
}
// server version [null terminated string]
// connection id [4 bytes]
pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 + 4
// first part of the password cipher [8 bytes]
authData := data[pos : pos+8]
// (filler) always 0x00 [1 byte]
pos += 8 + 1
// capability flags (lower 2 bytes) [2 bytes]
capabilities = capabilityFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))View on GitHub (pinned to c426bd9379)
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.
Example fix
// before — wrong port (e.g. Redis)
sql.Open("mysql", "user:pass@tcp(localhost:6379)/db")
// after
sql.Open("mysql", "user:pass@tcp(localhost:3306)/db") Defensive patterns
Strategy: validation
Validate before calling
// sanity-check that the endpoint speaks MySQL before opening the driver
conn, err := net.DialTimeout("tcp", addr, 5*time.Second)
if err != nil { return err }
banner := make([]byte, 1)
_, _ = conn.Read(banner)
conn.Close()
if banner[0] < 10 { return fmt.Errorf("endpoint %s is not a MySQL server", addr) } Try / catch
if err := db.Ping(); err != nil {
if strings.Contains(err.Error(), "unsupported protocol version") {
// the endpoint is not MySQL; verify host/port and proxies
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- invalid connection
- invalid max_allowed_packet value (%q): %w
- unknown collation: %q
- default addr for network '{cfg.Net}' unknown
- TLS requested but server does not support TLS
AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04).
Data as JSON: /data/errors/8af64579bab14a5d.json.
Report an issue: GitHub.