{"record":{"id":"83945b5f86e9e538","repo":"gravitational/teleport","slug":"failed-to-fetch-mysql-version","errorCode":null,"errorMessage":"failed to fetch MySQL version","messagePattern":"failed to fetch MySQL version","errorType":"exception","errorClass":"ConnectionProblem","httpStatus":null,"severity":"error","filePath":"lib/srv/db/mysql/protocol/version.go","lineNumber":106,"sourceCode":"\tversionLength := bytes.IndexByte(handshake[1:], 0x00)\n\tif versionLength == -1 {\n\t\treturn \"\", trace.Errorf(\"failed to read the MySQL server version\")\n\t}\n\n\treturn string(handshake[1 : 1+versionLength]), nil\n}\n\n// readHandshakeError reads and returns an error message from\nfunc readHandshakeError(connBuf io.Reader) (string, error) {\n\thandshakePacket, err := ParsePacket(connBuf)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\terrPackage, ok := handshakePacket.(*Error)\n\tif !ok {\n\t\treturn \"\", trace.BadParameter(\"expected MySQL error package, got %T\", handshakePacket)\n\t}\n\treturn \"\", trace.ConnectionProblem(errors.New(\"failed to fetch MySQL version\"), \"%s\", errPackage.Error())\n}\n\n// IsHandshakeV10Packet peeks into the conn and checks for a handshake v10 packet.\n// The results of this function are only meaningful during the connection phase\n// of the MySQL protocol. It is the caller's responsibility to only use this\n// function during the connection phase.\n// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_handshake_v10.html\nfunc IsHandshakeV10Packet(conn BufferedConn) (bool, error) {\n\tpkgHeaderAndType, err := conn.Peek(packetHeaderAndTypeSize)\n\tif err != nil {\n\t\treturn false, trace.Wrap(err)\n\t}\n\tconst typeIdx = packetHeaderAndTypeSize - 1\n\treturn pkgHeaderAndType[typeIdx] == 10, nil\n}\n\n// BufferedConn is a net.Conn wrapper with additional Peek() method.\ntype BufferedConn struct {","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/gravitational/teleport/blob/1283425b60ec5f60d509ba4c791183d452923ff7/lib/srv/db/mysql/protocol/version.go#L88-L124","documentation":"'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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// probe reachability and avoid hammering the server into a blocked state\nif err := tcpProbe(mysqlHost, mysqlPort); err != nil {\n  return fmt.Errorf(\"mysql unreachable before version probe: %w\", err)\n}","typeGuard":"func isMySQLVersionFetchError(err error) bool {\n  return trace.IsConnectionProblem(err) && strings.Contains(err.Error(), \"failed to fetch MySQL version\")\n}","tryCatchPattern":"ver, err := protocol.ReadMySQLVersion(ctx, conn)\nif err != nil {\n  if isMySQLVersionFetchError(err) {\n    log.Printf(\"mysql refused version probe: %v\", trace.Unwrap(err))\n    return mysqlDefaultVersion, nil // or surface the server's error text\n  }\n  return err\n}","preventionTips":["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"],"tags":["mysql","database","protocol","teleport"],"backgroundTag":"mysql-handshake-error","analyzedSha":"1283425b60ec5f60d509ba4c791183d452923ff7","analyzedAt":"2026-09-02T04:06:41.601Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}