vitessio/vitess · error
failed parsing primary_term_start_time %s: %w
Error message
failed parsing primary_term_start_time %s: %w
What it means
Thrown by parseTablet when the tablet record carries a primary_term_start_time string that fails to parse as RFC3339 (time.Parse(time.RFC3339, ...)). Primary term start time marks when the current PRIMARY tablet's term began, and vtadmin expects it serialized in RFC3339 (e.g. 2023-01-02T15:04:05Z).
Source
Thrown at go/vt/vtadmin/cluster/cluster.go:340
return nil, err
}
tablet.State = vtadminproto.ParseTabletServingState(servingStateStr)
topotablet.Alias, err = topoproto.ParseTabletAlias(aliasStr)
if err != nil {
return nil, fmt.Errorf("failed to parse tablet_alias %s: %w", aliasStr, err)
}
if topotablet.Alias.Cell != cell {
// (TODO:@amason) ???
log.Warn(fmt.Sprintf("tablet cell %s does not match alias %s. ignoring for now", cell, topoproto.TabletAliasString(topotablet.Alias)))
}
if mtstStr != "" {
timeTime, err := time.Parse(time.RFC3339, mtstStr)
if err != nil {
return nil, fmt.Errorf("failed parsing primary_term_start_time %s: %w", mtstStr, err)
}
topotablet.PrimaryTermStartTime = protoutil.TimeToProto(timeTime)
}
if c.TabletFQDNTmpl != nil {
tablet.FQDN, err = textutil.ExecuteTemplate(c.TabletFQDNTmpl, tablet)
if err != nil {
return nil, fmt.Errorf("failed to execute tablet FQDN template for %+v: %w", tablet, err)
}
}
return tablet, nil
}
// ApplySchema applies a schema to the given keyspace in this cluster.
func (c *Cluster) ApplySchema(ctx context.Context, req *vtctldatapb.ApplySchemaRequest) (*vtctldatapb.ApplySchemaResponse, error) {
span, ctx := trace.NewSpan(ctx, "Cluster.ApplySchema")View on GitHub (pinned to 01a25a7d17)
Solutions
- Check the primary_term_start_time value in the error message; convert the source to RFC3339 (e.g. `time.Unix(ts,0).UTC().Format(time.RFC3339)`).
- If the value came from custom scripts/tooling, fix them to emit RFC3339 timestamps.
- Upgrade/downgrade vtctld and vttablets so all components serialize times consistently (vitess protoutil conventions).
- If the field should be unset, clear it so the empty-string guard (mtstStr != "") skips parsing.
Example fix
// before mtstStr = "1672674245" // unix seconds, not RFC3339 // after mtstStr = "2023-01-02T15:04:05Z" // time.Unix(1672674245,0).UTC().Format(time.RFC3339)
Defensive patterns
Strategy: validation
Validate before calling
mtstStr := "2023-01-02T15:04:05Z"
if _, err := time.Parse(time.RFC3339, mtstStr); err != nil {
return fmt.Errorf("primary_term_start_time %q is not RFC3339", mtstStr)
} Type guard
func isRFC3339(s string) bool {
_, err := time.Parse(time.RFC3339, s)
return err == nil
} Prevention
- Serialize all timestamps with protoutil.TimeToProto / time.RFC3339, never raw unix integers.
- Write a unit check for any custom tooling that writes tablet records to the topo.
- Leave the field empty rather than writing a placeholder non-parseable value.
When it happens
Trigger: Discovering tablets via parseTablets where the source record's primary_term_start_time field is non-empty but not RFC3339-formatted — e.g. a unix timestamp integer, a partial datetime, or locale-formatted time.
Common situations: Custom tooling or scripts writing tablet records with unix-epoch timestamps instead of RFC3339 strings; vttablet/vtctld version mismatch producing a different time serialization; hand-crafted test topo data.
Related errors
- failed to delete tablet: %w
- Error setting tablet to read-only: %w
- Error setting tablet to read-write: %w
- not allowed: deny-all security-policy enforced
- not allowed: read-only security-policy enforced
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/86b4a642fb3a0cfa.
Report an issue: GitHub.