vitessio/vitess · critical
failed to parse pos column: %v
Error message
failed to parse pos column: %v
What it means
The pos column holds the stream's current replication position (GTID set), encoded with replication.EncodePosition. DecodePosition failed, so the stored position string is not a valid GTID set for the flavor (MySQL or MariaDB) or is empty/unreadable.
Source
Thrown at go/vt/binlog/binlogplayer/binlog_player.go:595
return VRSettings{}, fmt.Errorf("error %v in selecting vreplication settings %v", err, query)
}
if len(qr.Rows) != 1 {
return VRSettings{}, fmt.Errorf("checkpoint information not available in db for %v", uid)
}
vrRow := qr.Named().Row()
maxTPS, err := vrRow.ToInt64("max_tps")
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse max_tps column: %v", err)
}
maxReplicationLag, err := vrRow.ToInt64("max_replication_lag")
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse max_replication_lag column: %v", err)
}
startPos, err := DecodePosition(vrRow.AsString("pos", ""))
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse pos column: %v", err)
}
stopPos, err := replication.DecodePosition(vrRow.AsString("stop_pos", ""))
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse stop_pos column: %v", err)
}
workflowType, err := vrRow.ToInt32("workflow_type")
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse workflow_type column: %v", err)
}
workflowSubType, err := vrRow.ToInt32("workflow_sub_type")
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse workflow_sub_type column: %v", err)
}
deferSecondaryKeys, err := vrRow.ToBool("defer_secondary_keys")
if err != nil {
return VRSettings{}, fmt.Errorf("failed to parse defer_secondary_keys column: %v", err)
}
options := vrRow.AsString("options", "{}")View on GitHub (pinned to 01a25a7d17)
Solutions
- Read the stored value: `select uid, pos from _vt.vreplication where uid=<id>` and verify it is a valid GTID set (e.g. MySQL: `3E11FA47-...:1-5`).
- If invalid, resync the stream: start a fresh workflow or reset pos to a valid position captured from the source (`SHOW MASTER STATUS` / `SELECT @@gtid_executed`).
- Ensure the source and target MySQL flavors match; mixed MySQL/MariaDB GTID sets cannot be decoded.
- Do not hand-edit pos; use vtctldclient/VExec workflow operations.
Example fix
// before: invalid/empty pos stored manually update _vt.vreplication set pos='' where uid=1; // after: valid MySQL GTID set update _vt.vreplication set pos='MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5' where uid=1;
Defensive patterns
Strategy: validation
Validate before calling
qr, _ := dbClient.ExecuteFetch(fmt.Sprintf("SELECT pos FROM _vt.vreplication WHERE uid=%d", uid), 1)
if len(qr.Rows) == 1 {
p := qr.Named().Row().AsString("pos", "")
if _, err := replication.DecodePosition(p); err != nil {
return fmt.Errorf("pos %q is not a decodable position for this flavor; resync the stream", p)
}
} Type guard
func isValidGTIDPosition(pos string) bool {
if pos == "" { return false }
_, err := replication.DecodePosition(pos)
return err == nil
} Try / catch
settings, err := binlogplayer.ReadVRSettings(dbClient, uid)
if err != nil && strings.Contains(err.Error(), "failed to parse pos") {
// position unrecoverable: stop the stream cleanly and restart the workflow
return restartWorkflow(ctx, uid)
} Prevention
- Never hand-edit pos; only the player or workflow API should write it.
- Keep source and target MySQL flavors identical (MySQL vs MariaDB GTID).
- When copying clusters, regenerate positions from the actual source, don't copy rows verbatim.
- Validate a position with replication.DecodePosition before persisting it.
When it happens
Trigger: DecodePosition(vrRow.AsString("pos", "")) errors: pos contains an empty string (default used when SQL NULL), a truncated value, a position from a different flavor (e.g. MariaDB GTID in a MySQL tablet), or arbitrary text from manual edits.
Common situations: Restoring a target MySQL from a MariaDB source backup (or vice versa); manual updates to pos; pos truncated by column-size limits in hand-edited rows; copying _vt.vreplication rows between clusters with different GTID setups.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse stop_pos column: %v
- failed to parse max_tps column: %v
- failed to parse max_replication_lag column: %v
- failed to parse options column: %v
- empty gtid passed to setPosition
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/a017f2c20ccd26af.
Report an issue: GitHub.