vitessio/vitess · error

source shard %v is not in serving state

Error message

source shard %v is not in serving state

What it means

During reshard setup, buildResharder requires every source shard's primary to be serving (`IsPrimaryServing` true in the topo). If a source shard is not serving, the reshard would silently lose binlog/VReplication data, so it aborts with this error before starting.

Source

Thrown at go/vt/wrangler/resharder.go:124

}

func (wr *Wrangler) buildResharder(ctx context.Context, keyspace, workflow string, sources, targets []string, cell, tabletTypes string) (*resharder, error) {
	rs := &resharder{
		wr:              wr,
		keyspace:        keyspace,
		workflow:        workflow,
		sourcePrimaries: make(map[string]*topo.TabletInfo),
		targetPrimaries: make(map[string]*topo.TabletInfo),
		cell:            cell,
		tabletTypes:     tabletTypes,
	}
	for _, shard := range sources {
		si, err := wr.ts.GetShard(ctx, keyspace, shard)
		if err != nil {
			return nil, vterrors.Wrapf(err, "GetShard(%s) failed", shard)
		}
		if !si.IsPrimaryServing {
			return nil, fmt.Errorf("source shard %v is not in serving state", shard)
		}
		rs.sourceShards = append(rs.sourceShards, si)
		primary, err := wr.ts.GetTablet(ctx, si.PrimaryAlias)
		if err != nil {
			return nil, vterrors.Wrapf(err, "GetTablet(%s) failed", si.PrimaryAlias)
		}
		rs.sourcePrimaries[si.ShardName()] = primary
	}
	for _, shard := range targets {
		si, err := wr.ts.GetShard(ctx, keyspace, shard)
		if err != nil {
			return nil, vterrors.Wrapf(err, "GetShard(%s) failed", shard)
		}
		if si.IsPrimaryServing {
			return nil, fmt.Errorf("target shard %v is in serving state", shard)
		}
		rs.targetShards = append(rs.targetShards, si)
		primary, err := wr.ts.GetTablet(ctx, si.PrimaryAlias)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check `vtctlclient GetShard <keyspace>/<shard>` for IsPrimaryServing on each source shard.
  2. If serving was disabled intentionally, re-enable: `vtctlclient SetShardIsPrimaryServing <keyspace>/<shard> true`.
  3. If the primary tablet is down, repair it (restart vttablet, run reparent) until the shard serves.
  4. Re-run the Reshard command once all source shards report serving=true.

Example fix

// before
$ vtctlclient SetShardIsPrimaryServing commerce/0 false
// after
$ vtctlclient SetShardIsPrimaryServing commerce/0 true
$ vtctlclient Reshard commerce.reshard - -80,80-
Defensive patterns

Strategy: validation

Validate before calling

for _, shard := range sourceShards {
    si, err := ts.GetShard(ctx, keyspace, shard)
    if err != nil { return err }
    if !si.IsPrimaryServing {
        return fmt.Errorf("pre-flight: source shard %s is not serving", shard)
    }
}

Type guard

func sourceIsServing(si *topo.ShardInfo) bool { return si.IsPrimaryServing }

Try / catch

err := wr.Reshard(ctx, keyspace, workflow, sources, targets, opts...)
if err != nil && strings.Contains(err.Error(), "not in serving state") {
    log.Error("source shard must serve before reshard", slog.Any("error", err))
    // repair serving state then retry
}

Prevention

When it happens

Trigger: Calling Reshard (e.g. `vtctlclient Reshard <keyspace>.<workflow> <source_shards> <target_shards>`) while one of the source shards has IsPrimaryServing=false — primary tablet down, serving removed via SetShardIsPrimaryServing, or shard mid-reparent.

Common situations: Primary tablet crashed and was not replaced before starting the reshard; an operator disabled serving on a shard during maintenance and forgot to re-enable; tablet registered but not yet serving after provisioning.

Related errors


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