vitessio/vitess · error

failed to parse max_replication_lag column: %v

Error message

failed to parse max_replication_lag column: %v

What it means

Same conversion failure as max_tps but for the max_replication_lag column, which throttles vreplication based on source lag. A non-integer value in the checkpoint row aborts loading of settings for the stream.

Source

Thrown at go/vt/binlog/binlogplayer/binlog_player.go:591

func ReadVRSettings(dbClient DBClient, uid int32) (VRSettings, error) {
	query := fmt.Sprintf(GetWorkflowQuery, uid)
	qr, err := dbClient.ExecuteFetch(query, 1)
	if err != nil {
		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")

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the value: `select uid, max_replication_lag from _vt.vreplication where uid=<id>`.
  2. Correct it via `update _vt.vreplication set max_replication_lag=<seconds> where uid=<id>` (e.g. 10 or 9223372036854775807 for disabled).
  3. Restore the canonical _vt.vreplication schema if column types drifted after a version upgrade/downgrade.

Example fix

// before
update _vt.vreplication set max_replication_lag=NULL where uid=1;
// after
update _vt.vreplication set max_replication_lag=10 where uid=1;
Defensive patterns

Strategy: validation

Validate before calling

qr, _ := dbClient.ExecuteFetch(fmt.Sprintf("SELECT max_replication_lag FROM _vt.vreplication WHERE uid=%d", uid), 1)
if len(qr.Rows) == 1 {
	v := qr.Named().Row().AsString("max_replication_lag", "")
	if _, err := strconv.ParseInt(v, 10, 64); err != nil {
		return fmt.Errorf("max_replication_lag is not an integer (%q)", v)
	}
}

Type guard

func isNumeric(s string) bool {
	_, err := strconv.ParseInt(s, 10, 64)
	return err == nil
}

Try / catch

settings, err := binlogplayer.ReadVRSettings(dbClient, uid)
if err != nil && strings.Contains(err.Error(), "failed to parse max_replication_lag") {
	_, _ = dbClient.ExecuteFetch(fmt.Sprintf("UPDATE _vt.vreplication SET max_replication_lag=%d WHERE uid=%d", 10, uid), 0)
	settings, err = binlogplayer.ReadVRSettings(dbClient, uid)
}

Prevention

When it happens

Trigger: vrRow.ToInt64("max_replication_lag") fails: non-numeric or NULL value stored in the column, or schema drift between Vitess versions changing the column representation.

Common situations: Manual row edits; restoring _vt tables from a mismatched-version backup; corrupted row from an interrupted insert.

Understand the failure class

Related errors


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