vitessio/vitess · error

streams are mismatched across source shards for workflow: %s

Error message

streams are mismatched across source shards for workflow: %s

What it means

Before migrating streams, the code builds a reference set of (BinlogSource, cell, tabletTypes) tuples from the first source shard and requires every other source shard to have exactly the same stream set. If a later shard contains a stream whose key is not in the reference set, the streams are inconsistent and migration is aborted with this error naming the workflow.

Source

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

			}
			isReference, err := rs.blsIsReference(&bls)
			if err != nil {
				return vterrors.Wrap(err, "blsIsReference")
			}
			if !isReference {
				continue
			}
			key := fmt.Sprintf("%s:%s:%s", workflow, bls.Keyspace, bls.Shard)
			if mustCreate {
				rs.refStreams[key] = &refStream{
					workflow:    workflow,
					bls:         &bls,
					cell:        row[2].ToString(),
					tabletTypes: row[3].ToString(),
				}
			} else {
				if !ref[key] {
					return fmt.Errorf("streams are mismatched across source shards for workflow: %s", workflow)
				}
				delete(ref, key)
			}
		}
		if len(ref) != 0 {
			return fmt.Errorf("streams are mismatched across source shards: %v", ref)
		}
		return nil
	})
	return err
}

// blsIsReference is partially copied from streamMigrater.templatize.
// It reuses the constants from that function also.
func (rs *resharder) blsIsReference(bls *binlogdatapb.BinlogSource) (bool, error) {
	streamType := workflow.StreamTypeUnknown
	for _, rule := range bls.Filter.Rules {
		typ, err := rs.identifyRuleType(rule)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Dump streams on all source shards: `SELECT workflow, binlog_source, cell, tablet_types FROM _vt.vreplication;` on each source primary.
  2. Diff the binlog_source/cell/tablet_types tuples against the reference shard and correct the mismatched shard (delete and recreate its stream to match the others).
  3. If the workflow is obsolete on the odd shard, delete that row rather than reconciling it.
  4. Re-run the reshard; if you still see mismatches, repeat until every source shard's stream set is identical.

Example fix

-- before: shard 0 filter = {table:'t1'}, shard 1 filter = {table:'t2'}
UPDATE _vt.vreplication SET binlog_source = <same as shard 0> WHERE workflow='w' AND rid=<id>;
-- after: both shards have identical binlog_source
Defensive patterns

Strategy: validation

Validate before calling

var ref []string
for each source shard {
    keys := streamKeys(shard) // binlog_source|cell|tablet_types tuples
    if ref == nil { ref = keys; continue }
    if !equalSets(ref, keys) { return fmt.Errorf("streams differ across shards") }
}

Type guard

func streamSetsEqual(a, b map[string]bool) bool { return maps.Equal(a, b) }

Try / catch

if err := wr.Reshard(...); err != nil {
    if strings.Contains(err.Error(), "streams are mismatched") {
        return reconcileStreamsAcrossShards(ctx, workflow)
    }
    return err
}

Prevention

When it happens

Trigger: Running Reshard when source shards' `_vt.vreplication` rows for a workflow do not match across shards — e.g. one shard has an extra filter rule or different keyspace/table settings than the others.

Common situations: A stream was created/edited on only one shard (manual VDP operations); a prior partial migration updated some shards but not others; filter rules were modified on one shard's streams during an emergency.

Related errors


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