gravitational/teleport · error · ConnectionProblem
failed to fetch MySQL version
Error message
failed to fetch MySQL version
What it means
'failed to fetch MySQL version' is raised by readHandshakeError (called from ReadMySQLVersion) in lib/srv/db/mysql/protocol/version.go. When probing a MySQL server's version, Teleport receives an error packet instead of a handshake packet; the code wraps the raw MySQL error packet inside a trace.ConnectionProblem with this message.
Source
Thrown at lib/srv/db/mysql/protocol/version.go:106
versionLength := bytes.IndexByte(handshake[1:], 0x00)
if versionLength == -1 {
return "", trace.Errorf("failed to read the MySQL server version")
}
return string(handshake[1 : 1+versionLength]), nil
}
// readHandshakeError reads and returns an error message from
func readHandshakeError(connBuf io.Reader) (string, error) {
handshakePacket, err := ParsePacket(connBuf)
if err != nil {
return "", err
}
errPackage, ok := handshakePacket.(*Error)
if !ok {
return "", trace.BadParameter("expected MySQL error package, got %T", handshakePacket)
}
return "", trace.ConnectionProblem(errors.New("failed to fetch MySQL version"), "%s", errPackage.Error())
}
// IsHandshakeV10Packet peeks into the conn and checks for a handshake v10 packet.
// The results of this function are only meaningful during the connection phase
// of the MySQL protocol. It is the caller's responsibility to only use this
// function during the connection phase.
// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_handshake_v10.html
func IsHandshakeV10Packet(conn BufferedConn) (bool, error) {
pkgHeaderAndType, err := conn.Peek(packetHeaderAndTypeSize)
if err != nil {
return false, trace.Wrap(err)
}
const typeIdx = packetHeaderAndTypeSize - 1
return pkgHeaderAndType[typeIdx] == 10, nil
}
// BufferedConn is a net.Conn wrapper with additional Peek() method.
type BufferedConn struct {View on GitHub (pinned to 1283425b60)
Solutions
- Run 'mysqladmin flush-hosts' or restart MySQL if the host is blocked due to connection errors
- Check the server error log for the underlying MySQL error packet text
- Raise max_connections or fix connection leaks if the server is out of connections
- Verify you are pointing at the correct MySQL port and that the probe's TLS settings match the server requirements
Defensive patterns
Strategy: type-guard
Validate before calling
// probe reachability and avoid hammering the server into a blocked state
if err := tcpProbe(mysqlHost, mysqlPort); err != nil {
return fmt.Errorf("mysql unreachable before version probe: %w", err)
} Type guard
func isMySQLVersionFetchError(err error) bool {
return trace.IsConnectionProblem(err) && strings.Contains(err.Error(), "failed to fetch MySQL version")
} Try / catch
ver, err := protocol.ReadMySQLVersion(ctx, conn)
if err != nil {
if isMySQLVersionFetchError(err) {
log.Printf("mysql refused version probe: %v", trace.Unwrap(err))
return mysqlDefaultVersion, nil // or surface the server's error text
}
return err
} Prevention
- Flush hosts / fix blocked-host conditions before re-probing
- Respect max_connections to avoid filling the connection pool
- Point probes at the real MySQL port with matching TLS settings
When it happens
Trigger: ReadMySQLVersion connects to a MySQL server and the first packet received is *protocol.Error rather than a HandshakeV10 — e.g. the server rejects the pre-auth probe due to blocked host, too many connections, or auth/SSL requirements.
Common situations: MySQL server reports 'Host ... is blocked because of many connection errors', max_connections exceeded, or connecting to something that is not a standard MySQL endpoint (e.g. a proxy or a TLS-only port).
Related errors
- unable to serve request due to an app configuration error. C
- unable to serve the request due to an internal error. Contac
- tokens quota exceeded. Contact your Teleport administrator
- the inference provider returned an unexpected error. Contact
- session chunk already closed
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/83945b5f86e9e538.
Report an issue: GitHub.