{"record":{"id":"6de3b9fb3783265a","repo":"vitessio/vitess","slug":"binlog-stream-client-charset-v-doesn-t-match-se","errorCode":null,"errorMessage":"binlog stream client charset (%v) doesn't match server (%v)","messagePattern":"binlog stream client charset \\((.+?)\\) doesn't match server \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/binlog/binlog_streamer.go","lineNumber":208,"sourceCode":"\t\treturn err\n\t}\n\tdefer bls.conn.Close()\n\n\t// Check that the default charsets match, if the client specified one.\n\t// Note that Streamer uses the settings for the 'dba' user, while\n\t// BinlogPlayer uses the 'filtered' user, so those are the ones whose charset\n\t// must match. Filtered replication should still succeed even with a default\n\t// mismatch, since we pass per-statement charset info. However, Vitess in\n\t// general doesn't support servers with different default charsets, so we\n\t// treat it as a configuration error.\n\tif bls.clientCharset != nil {\n\t\tcs, err := mysql.GetCharset(bls.conn.Conn)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"can't get charset to check binlog stream: %v\", err)\n\t\t}\n\t\tlog.Info(fmt.Sprintf(\"binlog stream client charset = %v, server charset = %v\", bls.clientCharset, cs))\n\t\tif !proto.Equal(cs, bls.clientCharset) {\n\t\t\treturn fmt.Errorf(\"binlog stream client charset (%v) doesn't match server (%v)\", bls.clientCharset, cs)\n\t\t}\n\t}\n\n\tvar events <-chan mysql.BinlogEvent\n\tvar errs <-chan error\n\tif bls.timestamp != 0 {\n\t\t// MySQL 5.6 only: We are going to start reading the\n\t\t// logs from the beginning of a binlog file. That is\n\t\t// going to send us the PREVIOUS_GTIDS_EVENT that\n\t\t// contains the starting GTIDSet, and we will save\n\t\t// that as the current position.\n\t\tbls.usePreviousGTIDs = true\n\t\tevents, errs, err = bls.conn.StartBinlogDumpFromBinlogBeforeTimestamp(ctx, bls.timestamp)\n\t} else if !bls.startPos.IsZero() {\n\t\t// MySQL 5.6 only: we are starting from a random\n\t\t// binlog position. It turns out we will receive a\n\t\t// PREVIOUS_GTIDS_EVENT event, that has a GTIDSet\n\t\t// extracted from the binlogs. It is not related to","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/binlog/binlog_streamer.go#L190-L226","documentation":"Vitess does not support a MySQL server whose default charset differs from the charset the binlog-streaming client was configured with. When Stream (via StreamKeyRange/StreamTables) starts, it compares the client-provided charset against the server's charset via proto.Equal and aborts on mismatch. This is treated as a configuration error even though filtered replication might otherwise tolerate it, because per-statement charset info assumes consistent defaults.","triggerScenarios":"Calling Stream with a clientCharset set (via NewStreamer) that is not proto.Equal to the server's default charset reported by mysql.GetCharset on the dba connection — e.g. client charset utf8mb4 vs server default latin1.","commonSituations":"Provisioned MySQL server with a different default charset than the vttablet/binlog source config; charset changed on the server (my.cnf character_set_server) after tablets were deployed; mixing tablets configured for different charsets in a cluster.","solutions":["Align the server default charset (character-set-server / collation-server) with the client charset Vitess is configured with, or vice versa","Update the vttablet binlog source charset config to match the server's default charset","Reinitialize or correct charset settings on the target MySQL instances so the dba-user connection reports the expected charset","After changing my.cnf, restart MySQL and the tablet so the new charset takes effect"],"exampleFix":"// before (my.cnf)\ncharacter-set-server = latin1\n// after\ncharacter-set-server = utf8mb4","handlingStrategy":"validation","validationCode":"serverCS, err := mysql.GetCharset(conn.Conn)\nif err != nil { return err }\nif !proto.Equal(serverCS, configuredCharset) {\n\treturn fmt.Errorf(\"charset mismatch: client %v vs server %v\", configuredCharset, serverCS)\n}","typeGuard":null,"tryCatchPattern":"if err := streamer.Stream(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"doesn't match server\") {\n\t\t// fix charset configuration; streaming will never succeed until then\n\t}\n}","preventionTips":["Keep character-set-server identical across all MySQL instances in the topology","Align vttablet binlog-source charset config with the server default","Avoid changing server charset without a coordinated rollout","Validate charsets during cluster provisioning"],"tags":["mysql","binlog","charset","configuration-mismatch"],"backgroundTag":"charset-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}