{"record":{"id":"fb13c27ec263762c","repo":"vitessio/vitess","slug":"no-primary-tablet-in-shard-s-s","errorCode":null,"errorMessage":"no primary tablet in shard %s/%s","messagePattern":"no primary tablet in shard (.+?)/(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/grpcvtctldserver/server.go","lineNumber":4911,"sourceCode":"\t\t// Validate all of the shards.\n\t\tshards, err = s.ts.GetShardNames(ctx, req.Keyspace)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif len(shards) == 0 {\n\t\treturn nil, fmt.Errorf(\"no shards found in keyspace %s\", req.Keyspace)\n\t}\n\tsort.Strings(shards)\n\n\t// Find the reference permissions using the first shard's primary.\n\tsi, err := s.ts.GetShard(ctx, req.Keyspace, shards[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !si.HasPrimary() {\n\t\treturn nil, fmt.Errorf(\"no primary tablet in shard %s/%s\", req.Keyspace, shards[0])\n\t}\n\treferenceAlias := si.PrimaryAlias\n\tlog.Info(\"Gathering permissions for reference primary \" + topoproto.TabletAliasString(referenceAlias))\n\tpres, err := s.GetPermissions(ctx, &vtctldatapb.GetPermissionsRequest{\n\t\tTabletAlias: si.PrimaryAlias,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treferencePermissions := pres.Permissions\n\n\t// Then diff the first/reference tablet with all the others.\n\teg, egctx := errgroup.WithContext(ctx)\n\tfor _, shard := range shards {\n\t\teg.Go(func() error {\n\t\t\taliases, err := s.ts.FindAllTabletAliasesInShard(egctx, req.Keyspace, shard)\n\t\t\tif err != nil {\n\t\t\t\treturn err","sourceCodeStart":4893,"sourceCodeEnd":4929,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/grpcvtctldserver/server.go#L4893-L4929","documentation":"Returned when the first shard of the source keyspace (used as the reference for permission copying) has no primary tablet — its shard record lacks a PrimaryAlias. The permission-copy flow needs a reference primary to read permissions from.","triggerScenarios":"Copy-permissions style RPC where shards[0].HasPrimary() is false — the shard has no elected/recorded primary, typically after a failed reparent or before initial tablet promotion.","commonSituations":"Shard initialized but never promoted to primary; reparent failed leaving PrimaryAlias empty; running the copy during a topology repair window.","solutions":["Restore a primary with `vtctldclient PlannedReparentShard <keyspace/shard>`","Verify with `vtctldclient GetShard <keyspace/shard>` that primary_alias is set","Re-run the permissions copy after the shard has a healthy primary","Pick a shard known to have a primary instead of relying on shards[0]"],"exampleFix":"// before\nif !si.HasPrimary() {\n    return nil, fmt.Errorf(\"no primary tablet in shard %s/%s\", req.Keyspace, shards[0])\n}\n// after\nif !si.HasPrimary() {\n    return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, \"no primary tablet in shard %s/%s; run PlannedReparentShard first\", req.Keyspace, shards[0])\n}","handlingStrategy":"validation","validationCode":"shard, _ := topoServer.GetShard(ctx, keyspace, shardName)\nif shard.PrimaryAlias == nil { /* no primary; run reparent first */ }","typeGuard":null,"tryCatchPattern":"try {\n  await client.copyPermissions(sourceKeyspace, shard)\n} catch (e) {\n  if (String(e).includes('no primary tablet in shard')) {\n    await client.plannedReparentShard(sourceKeyspace, shard)\n    await retryCopy()\n  } else { throw e }\n}","preventionTips":["Elect a primary for every shard before dependent operations","Detect primary-less shards with monitoring on shard records","Complete failed reparents before running copy flows","Validate primary_alias exists via GetShard as a preflight"],"tags":["topology","primary-tablet","shard","precondition"],"backgroundTag":"no-primary-elected","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}