vitessio/vitess · error

failed to parse max_tps column: %v

Error message

failed to parse max_tps column: %v

What it means

The max_tps column of the vreplication checkpoint row could not be converted to an int64 by the named-row helper. VRSettings.MaxTPS throttles event application; a corrupt or non-numeric value makes the settings unusable.

Source

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

	WorkflowOptions    *vtctldata.WorkflowOptions
}

// ReadVRSettings retrieves the settings for a vreplication stream.
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")

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Inspect the row: `select uid, max_tps from _vt.vreplication where uid=<id>` and check the stored value.
  2. Fix the value with VExec or SQL: `update _vt.vreplication set max_tps=<n> where uid=<id>` (a sane default is 2147483647 meaning unlimited).
  3. If the schema/column type is wrong, restore the canonical _vt.vreplication schema for your Vitess version.
  4. If corruption is from an external writer, find and stop whatever is modifying the row.

Example fix

// before
update _vt.vreplication set max_tps='fast' where uid=1;
// after
update _vt.vreplication set max_tps=2147483647 where uid=1;
Defensive patterns

Strategy: validation

Validate before calling

qr, _ := dbClient.ExecuteFetch(fmt.Sprintf("SELECT max_tps FROM _vt.vreplication WHERE uid=%d", uid), 1)
if len(qr.Rows) == 1 {
	v := qr.Named().Row().AsString("max_tps", "")
	if _, err := strconv.ParseInt(v, 10, 64); err != nil {
		return fmt.Errorf("max_tps is not an integer (%q); fix the row before proceeding", 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_tps") {
	_, _ = dbClient.ExecuteFetch(fmt.Sprintf("UPDATE _vt.vreplication SET max_tps=%d WHERE uid=%d", math.MaxInt32, uid), 0)
	settings, err = binlogplayer.ReadVRSettings(dbClient, uid)
}

Prevention

When it happens

Trigger: vrRow.ToInt64("max_tps") fails: the column holds a non-numeric string, NULL in a schema that lacks the ToInt64 NULL handling, or the row was written by an older/newer Vitess with a different column type.

Common situations: Manual edits to _vt.vreplication inserting garbage into max_tps; restores of _vt tables from dumps with altered types; partial writes during a crashed workflow insert.

Understand the failure class

Related errors


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