{"record":{"id":"7f845a875ef14a67","repo":"tikv/tikv","slug":"start-key-must-be-in-data-key-space","errorCode":null,"errorMessage":"start_key must be in data-key space","messagePattern":"start_key must be in data-key space","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"components/raftstore/src/coprocessor/split_check/half.rs","lineNumber":137,"sourceCode":"}\n\n/// Get region approximate middle key from an explicit encoded data-key range.\n///\n/// The provided range must be in the `keys::data_key` / `keys::data_end_key`\n/// space. It is clamped to region boundaries. When the resulting range is\n/// empty, returns `Ok(None)`.\npub fn get_region_approximate_middle_in_range(\n    db: &impl KvEngine,\n    region: &Region,\n    start_key: Option<&[u8]>,\n    end_key: Option<&[u8]>,\n) -> Result<Option<Vec<u8>>> {\n    let region_start_key = keys::enc_start_key(region);\n    let region_end_key = keys::enc_end_key(region);\n\n    if let Some(start_key) = start_key {\n        if !keys::validate_data_key(start_key) {\n            return box_try!(Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidInput,\n                \"start_key must be in data-key space\",\n            )));\n        }\n    }\n    if let Some(end_key) = end_key {\n        if !keys::validate_data_key(end_key) && end_key != keys::DATA_MAX_KEY {\n            return box_try!(Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidInput,\n                \"end_key must be in data-key space\",\n            )));\n        }\n    }\n    let start_key = match start_key {\n        Some(start_key) if start_key > region_start_key.as_slice() => start_key.to_vec(),\n        _ => region_start_key,\n    };\n    let end_key = match end_key {","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/tikv/tikv/blob/78aedc1c81ef3f7d8bacc6e9d09f56460f134937/components/raftstore/src/coprocessor/split_check/half.rs#L119-L155","documentation":"`get_region_approximate_middle_in_range` in components/raftstore/src/coprocessor/split_check/half.rs:137 requires caller-supplied `start_key` to be in the encoded data-key space. `keys::validate_data_key` fails for keys not beginning with the data prefix (e.g. raw/meta keys), so an io::Error with InvalidInput and \"start_key must be in data-key space\" is returned. The function computes a middle split key, which is only meaningful for data keys.","triggerScenarios":"Calling `get_region_approximate_middle_in_range` (or `get_region_approximate_middle` that forwards the range) with `Some(start_key)` where `keys::validate_data_key(start_key)` is false — i.e. the key is not in the data-key space (not a properly encoded user-data key).","commonSituations":"Passing a raw table key instead of the TiKV-encoded key; passing keys::ENC_PREFIX/meta keys; using un-encoded keys copied from another system; bucket/split-range tooling (e.g. region buckets or manual split commands) supplying out-of-space keys.","solutions":["Encode the start key with `keys::encode_data_key` / the `keys` module helpers so `validate_data_key` passes.","Confirm the key comes from the data CF space (starts with the data-key prefix 'z') before passing it.","If the intent is to cover from the region start, pass `None` for start_key instead of a non-data key.","Fix the caller (e.g. bucket rule or split request) that is generating out-of-space keys."],"exampleFix":"// before\nlet middle = get_region_approximate_middle(db, region, Some(raw_key.to_vec()), None, \"write\")?;\n// after\nlet enc_key = keys::encode_data_key(raw_key);\nassert!(keys::validate_data_key(&enc_key));\nlet middle = get_region_approximate_middle(db, region, Some(enc_key), None, \"write\")?;","handlingStrategy":"validation","validationCode":"use tikv_util::keybuilder // keys module\nif !keys::validate_data_key(&start_key) {\n    return Err(\"start_key must be encoded into data-key space\".into());\n}","typeGuard":"fn is_data_key(k: &[u8]) -> bool { keys::validate_data_key(k) }","tryCatchPattern":"match middle_result {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput\n        && e.to_string().contains(\"start_key must be in data-key space\") => {\n        // re-encode the key or pass None and retry\n    }\n    other => other?,\n}","preventionTips":["Always encode user keys with the keys::encode_data_key helpers before use.","Never pass raw/meta keys as split-range bounds.","Pass None instead of a placeholder start key when the range is unbounded.","Add a validate_data_key assert in tests for range-generating code."],"tags":["raftstore","split-check","invalid-input","key-encoding"],"backgroundTag":"key-not-in-data-space","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"}