{"record":{"id":"0f5e8b2ef9ead51e","repo":"vitessio/vitess","slug":"shard-v-v-has-no-primary","errorCode":null,"errorMessage":"shard %v/%v has no primary","messagePattern":"shard (.+?)/(.+?) has no primary","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/mysqlctl/builtinbackupengine.go","lineNumber":1833,"sourceCode":"\t\treturn false\n\t}\n\treturn true\n}\n\n// ShouldStartMySQLAfterRestore signifies if this backup engine needs to restart MySQL once the restore is completed.\nfunc (be *BuiltinBackupEngine) ShouldStartMySQLAfterRestore() bool {\n\treturn true\n}\n\nfunc (be *BuiltinBackupEngine) Name() string { return builtinBackupEngineName }\n\nfunc getPrimaryPosition(ctx context.Context, tmc tmclient.TabletManagerClient, ts *topo.Server, keyspace, shard string) (replication.Position, error) {\n\tsi, err := ts.GetShard(ctx, keyspace, shard)\n\tif err != nil {\n\t\treturn replication.Position{}, vterrors.Wrap(err, \"can't read shard\")\n\t}\n\tif topoproto.TabletAliasIsZero(si.PrimaryAlias) {\n\t\treturn replication.Position{}, fmt.Errorf(\"shard %v/%v has no primary\", keyspace, shard)\n\t}\n\tti, err := ts.GetTablet(ctx, si.PrimaryAlias)\n\tif err != nil {\n\t\treturn replication.Position{}, fmt.Errorf(\"can't get primary tablet record %v: %v\", topoproto.TabletAliasString(si.PrimaryAlias), err)\n\t}\n\tposStr, err := tmc.PrimaryPosition(ctx, ti.Tablet)\n\tif err != nil {\n\t\treturn replication.Position{}, fmt.Errorf(\"can't get primary replication position: %v\", err)\n\t}\n\tpos, err := replication.DecodePosition(posStr)\n\tif err != nil {\n\t\treturn replication.Position{}, fmt.Errorf(\"can't decode primary replication position %q: %v\", posStr, err)\n\t}\n\treturn pos, nil\n}\n\nfunc init() {\n\tBackupRestoreEngineMap[builtinBackupEngineName] = &BuiltinBackupEngine{}","sourceCodeStart":1815,"sourceCodeEnd":1851,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/mysqlctl/builtinbackupengine.go#L1815-L1851","documentation":"getPrimaryPosition reads the shard record from the topo to find the primary tablet and fetch its replication position (used for backup validation/restore checks). If the shard's PrimaryAlias is zero — meaning no primary has ever been elected or the shard record is uninitialized — this error is returned.","triggerScenarios":"Calling backup/restore paths that call getPrimaryPosition against a keyspace/shard whose topo shard record has no PrimaryAlias set (fresh shard without InitShardPrimary, or primary term ended without a new election).","commonSituations":"Running vtctldclient Backup on a shard with no serving primary; shard created but InitShardPrimary never run; primary alias cleared after failures and ERS not completed.","solutions":["Check the shard record: vtctldclient GetShard <keyspace>/<shard> — confirm PrimaryAlias is empty.","Run InitShardPrimary (or let Orchestrator/ERT complete) to elect a primary.","Verify you targeted the correct keyspace/shard names.","Retry the backup/restore operation once the primary is serving."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"si, err := ts.GetShard(ctx, keyspace, shard)\nif err != nil { return err }\nif topoproto.TabletAliasIsZero(si.PrimaryAlias) {\n\treturn fmt.Errorf(\"shard %s/%s has no primary; run InitShardPrimary first\", keyspace, shard)\n}","typeGuard":null,"tryCatchPattern":"if err := doBackupOrRestore(...); err != nil {\n\tif strings.Contains(err.Error(), \"has no primary\") {\n\t\t// elect a primary via InitShardPrimary / ERS, then retry\n\t}\n}","preventionTips":["Never run backups against shards without an elected primary.","Automate primary election (ERS/Orchestrator) so shards are never leaderless.","Validate shard topology in pre-backup checks."],"tags":["topo","shard","replication"],"backgroundTag":"no-primary-in-shard","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}