{"record":{"id":"470ed7cbf4d762ec","repo":"tikv/tikv","slug":"region-must-have-leader","errorCode":null,"errorMessage":"region must have leader","messagePattern":"region must have leader","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/tikv-ctl/src/main.rs","lineNumber":900,"sourceCode":"            ErrorKind::MissingRequiredArgument,\n            \"--pd is required for this command\",\n        );\n    });\n    let cfg = PdConfig::new(vec![pd]);\n    cfg.validate().unwrap();\n    RpcClient::new(&cfg, None, mgr).unwrap_or_else(|e| perror_and_exit(\"RpcClient::new\", e))\n}\n\nfn split_region(pd_client: &RpcClient, mgr: Arc<SecurityManager>, region_id: u64, key: Vec<u8>) {\n    let region = block_on(pd_client.get_region_by_id(region_id))\n        .expect(\"get_region_by_id should success\")\n        .expect(\"must have the region\");\n\n    let leader = pd_client\n        .get_region_info(region.get_start_key())\n        .expect(\"get_region_info should success\")\n        .leader\n        .expect(\"region must have leader\");\n\n    let store = pd_client\n        .get_store(leader.get_store_id())\n        .expect(\"get_store should success\");\n\n    let tikv_client = {\n        let cb = ChannelBuilder::new(Arc::new(Environment::new(1)));\n        let channel = mgr.connect(cb, store.get_address());\n        TikvClient::new(channel)\n    };\n\n    let mut req = SplitRegionRequest::default();\n    req.mut_context().set_region_id(region_id);\n    req.mut_context()\n        .set_region_epoch(region.get_region_epoch().clone());\n    req.set_split_key(key);\n\n    let resp = tikv_client","sourceCodeStart":882,"sourceCodeEnd":918,"githubUrl":"https://github.com/tikv/tikv/blob/78aedc1c81ef3f7d8bacc6e9d09f56460f134937/cmd/tikv-ctl/src/main.rs#L882-L918","documentation":"get_region_info returns region metadata including an Option<Leader>; None means the region currently has no leader (Raft has not elected one). split_region needs the leader to know which TiKV store to send the split request to, so it panics with 'region must have leader'.","triggerScenarios":"Querying a region whose Raft group is in the middle of leader election, is down (all replicas unreachable), or is newly created/split and has not elected a leader yet; the region's start key no longer maps to the same region after concurrent splits/merges.","commonSituations":"Running split during a cluster incident with down TiKV stores; splitting a region right after a merge or split storm while elections are pending; querying regions on a store that was destroyed without proper offlining.","solutions":["Check the region's Raft status: `tikv-ctl raft log -r <region_id>` and verify peer states; wait for a leader to be elected and retry.","Restore/downed TiKV stores first (`tikv-ctl --host <addr> ...`, check store states with pd-ctl `store`) so Raft can elect a leader.","Re-fetch region info by key — if the region boundaries changed, target the new region ID instead."],"exampleFix":"// before\n.leader\n.expect(\"region must have leader\");\n// after\nlet leader = match region_info.leader {\n    Some(l) if l.get_id() != 0 => l,\n    _ => { eprintln!(\"region has no leader yet; retry later\"); return; }\n};","handlingStrategy":"retry","validationCode":"// confirm the region has a leader via pd-ctl before splitting\n// pd-ctl region <region_id>  -> look for a non-empty \"leader\" field","typeGuard":null,"tryCatchPattern":"// treat missing leader as transient: retry after leader election\nfor _ in 0..3 {\n    if let Some(leader) = region_info.leader { break; }\n    sleep(Duration::from_secs(2));\n    region_info = refresh_region_info(...)?;\n}","preventionTips":["Restore down TiKV stores before administrative splits","Wait for election after merges/splits before issuing new admin commands","Monitor raft leader counts; alert on leaderless regions"],"tags":["tikv-ctl","raft","leader-election","panic"],"backgroundTag":"no-region-leader","analyzedSha":"78aedc1c81ef3f7d8bacc6e9d09f56460f134937","analyzedAt":"2026-09-03T23:31:32.398Z","contentChangedAt":"2026-09-03T23:31:32.398Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}