{"record":{"id":"0fa80345764ab217","repo":"tikv/tikv","slug":"internal-error-download-request-dispatcher-return","errorCode":null,"errorMessage":"internal error: download_request_dispatcher returned None despite non-empty ssts","messagePattern":"internal error: download_request_dispatcher returned None despite non-empty ssts","errorType":"exception","errorClass":"sst_importer::Error","httpStatus":null,"severity":"error","filePath":"src/import/sst_service.rs","lineNumber":1261,"sourceCode":"                    return;\n                }\n            }\n\n            // FIXME: batch_download() should be an async fn, to allow BR to cancel\n            // a download task.\n            // Unfortunately, this currently can't happen because the S3Storage\n            // is not Send + Sync. See the documentation of S3Storage for reason.\n            let cipher = req\n                .cipher_info\n                .to_owned()\n                .into_option()\n                .filter(|c| c.cipher_type != EncryptionMethod::Plaintext);\n\n            let basic_meta = match download_request_dispatcher(&req, false) {\n                Ok(Some(meta)) => meta,\n                Ok(None) => {\n                    // This should never happen since we've already checked ssts is not empty\n                    let error = sst_importer::Error::Io(std::io::Error::new(\n                        std::io::ErrorKind::InvalidInput,\n                        \"internal error: download_request_dispatcher returned None despite non-empty ssts\",\n                    ));\n                    let mut resp = DownloadResponse::default();\n                    resp.set_error(error.into());\n                    crate::send_rpc_response!(Ok(resp), sink, label, timer);\n                    return;\n                }\n                Err(error) => {\n                    let mut resp = DownloadResponse::default();\n                    resp.set_error(error.into());\n                    crate::send_rpc_response!(Ok(resp), sink, label, timer);\n                    return;\n                }\n            };\n\n            let region_id = basic_meta.get_region_id();\n            let tablet = match tablets.get(region_id) {","sourceCodeStart":1243,"sourceCodeEnd":1279,"githubUrl":"https://github.com/tikv/tikv/blob/78aedc1c81ef3f7d8bacc6e9d09f56460f134937/src/import/sst_service.rs#L1243-L1279","documentation":"In batch_download, after the request is confirmed to contain files, download_request_dispatcher(&req, false) is expected to yield Some(basic_meta). A None here means the dispatcher could not derive the request metadata even though ssts is non-empty — an invariant violation, so it is reported as an internal error rather than a client mistake.","triggerScenarios":"Dispatch logic in batch_download producing Ok(None) for a non-empty sst set — should be unreachable unless the request's internal metadata (e.g. required fields on ssts or the request) is malformed in a way the dispatcher silently ignores.","commonSituations":"A TiKV bug or a partially-initialized request; corrupted multi-file request where ssts exist but metadata needed by the dispatcher is missing; fuzzing or a client that writes ssts but leaves dispatch-relevant fields unset.","solutions":["Upgrade/patch TiKV — this is an internal invariant violation; report it with the request details","Inspect the request: ensure sst metadata fields required by download_request_dispatcher are populated","Retry the operation; if reproducible, collect logs and file a bug"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Ensure sst metadata required by the dispatcher is populated\nfor m in req.get_ssts() {\n    assert!(!m.get_cf().is_empty() && !m.get_sha256().is_empty());\n}","typeGuard":null,"tryCatchPattern":"let resp = client.batch_download(req).await?;\nif let Some(err) = resp.get_error() {\n    if err.get_message().contains(\"internal error\") {\n        log::error!(\"dispatcher invariant violated, reporting bug\");\n        return Err(err.into()); // escalate/upgrade TiKV\n    }\n    return Err(err.into());\n}","preventionTips":["Keep TiKV patched — this path should be unreachable","Fully populate SstMeta fields before sending batch requests","File a bug with request details if reproducible","Monitor logs for 'internal error: download_request_dispatcher' occurrences"],"tags":["rust","import","internal-error","invariant-violation"],"backgroundTag":"internal-invariant-violation","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"}