{"record":{"id":"e35e30116074a3ea","repo":"vitessio/vitess","slug":"can-t-decode-primary-replication-position-q-v","errorCode":null,"errorMessage":"can't decode primary replication position %q: %v","messagePattern":"can't decode primary replication position %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/mysqlctl/builtinbackupengine.go","lineNumber":1845,"sourceCode":"func getPrimaryPosition(ctx context.Context, tmc tmclient.TabletManagerClient, ts *topo.Server, keyspace, shard string) (replication.Position, error) {\n\tsi, err := ts.GetShard(ctx, keyspace, shard)\n\tif err != nil {\n\t\treturn replication.Position{}, vterrors.Wrap(err, \"can't read shard\")\n\t}\n\tif topoproto.TabletAliasIsZero(si.PrimaryAlias) {\n\t\treturn replication.Position{}, fmt.Errorf(\"shard %v/%v has no primary\", keyspace, shard)\n\t}\n\tti, err := ts.GetTablet(ctx, si.PrimaryAlias)\n\tif err != nil {\n\t\treturn replication.Position{}, fmt.Errorf(\"can't get primary tablet record %v: %v\", topoproto.TabletAliasString(si.PrimaryAlias), err)\n\t}\n\tposStr, err := tmc.PrimaryPosition(ctx, ti.Tablet)\n\tif err != nil {\n\t\treturn replication.Position{}, fmt.Errorf(\"can't get primary replication position: %v\", err)\n\t}\n\tpos, err := replication.DecodePosition(posStr)\n\tif err != nil {\n\t\treturn replication.Position{}, fmt.Errorf(\"can't decode primary replication position %q: %v\", posStr, err)\n\t}\n\treturn pos, nil\n}\n\nfunc init() {\n\tBackupRestoreEngineMap[builtinBackupEngineName] = &BuiltinBackupEngine{}\n}\n\n// closeWithRetry does just what it says. Retrying a close operation is important as\n// an error is most likely transient/ephemeral and leaving around open file descriptors\n// can lead to later problems as the file may be in a sort-of uploaded state where it\n// exists but has not yet been finalized (this is true for GCS). This can cause\n// unexpected behavior if you retry the file while the original request is still in this\n// state. Most implementations such as GCS will automatically retry operations, but close\n// is one that may be left to the caller (this is true for GCS).\n// We model this retry after the GCS retry implementation described here:\n// https://cloud.google.com/storage/docs/retry-strategy#go\nfunc closeWithRetry(ctx context.Context, logger logutil.Logger, file io.Closer, name string) error {","sourceCodeStart":1827,"sourceCodeEnd":1863,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/mysqlctl/builtinbackupengine.go#L1827-L1863","documentation":"The position string returned by the primary's PrimaryPosition RPC is decoded with replication.DecodePosition. If the string is not a valid GTID position for the expected flavor, this error reports the offending string and the decode cause. It indicates the position format is unrecognized or corrupt.","triggerScenarios":"replication.DecodePosition(posStr) fails because the primary returned a position in an unexpected format — e.g. MariaDB GTID string handled by MySQL-flavored parsing, an empty/garbage string from the tablet, or mixed-version components with incompatible position encodings.","commonSituations":"Mixed MySQL/MariaDB flavors in one cluster; tablet returning an empty position when mysqld is misconfigured; rolling upgrade where an older/newer component emits an unfamiliar position format.","solutions":["Inspect the quoted position string in the message to identify the flavor/format.","Confirm all tablets in the shard run the same MySQL flavor and compatible Vitess version.","Check mysqld GTID configuration on the primary (gtid_mode, binlog settings).","If caused by mixed versions, complete the rolling upgrade and retry."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"pos, err := replication.DecodePosition(posStr)\nif err != nil {\n\treturn fmt.Errorf(\"primary returned undecodable position %q; check MySQL flavor/GTID config\", posStr)\n}","typeGuard":null,"tryCatchPattern":"if err := runBackup(...); err != nil {\n\tif strings.Contains(err.Error(), \"can't decode primary replication position\") {\n\t\t// verify flavor consistency and mysqld GTID settings, then retry\n\t}\n}","preventionTips":["Run a single MySQL flavor per cluster (never mix MySQL and MariaDB).","Keep Vitess versions in sync across rolling upgrades.","Verify gtid_mode/binlog configuration on primaries."],"tags":["replication","gtid","version-compatibility"],"backgroundTag":"position-decode-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}