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

  1. 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`).
  2. 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`).
  3. Ensure the source and target MySQL flavors match; mixed MySQL/MariaDB GTID sets cannot be decoded.
  4. 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

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

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/a017f2c20ccd26af. Report an issue: GitHub.