tikv/tikv · error · sst_importer::Error

internal error: download_request_dispatcher returned None de

Error message

internal error: download_request_dispatcher returned None despite non-empty ssts

What it means

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.

Source

Thrown at src/import/sst_service.rs:1261

                    return;
                }
            }

            // FIXME: batch_download() should be an async fn, to allow BR to cancel
            // a download task.
            // Unfortunately, this currently can't happen because the S3Storage
            // is not Send + Sync. See the documentation of S3Storage for reason.
            let cipher = req
                .cipher_info
                .to_owned()
                .into_option()
                .filter(|c| c.cipher_type != EncryptionMethod::Plaintext);

            let basic_meta = match download_request_dispatcher(&req, false) {
                Ok(Some(meta)) => meta,
                Ok(None) => {
                    // This should never happen since we've already checked ssts is not empty
                    let error = sst_importer::Error::Io(std::io::Error::new(
                        std::io::ErrorKind::InvalidInput,
                        "internal error: download_request_dispatcher returned None despite non-empty ssts",
                    ));
                    let mut resp = DownloadResponse::default();
                    resp.set_error(error.into());
                    crate::send_rpc_response!(Ok(resp), sink, label, timer);
                    return;
                }
                Err(error) => {
                    let mut resp = DownloadResponse::default();
                    resp.set_error(error.into());
                    crate::send_rpc_response!(Ok(resp), sink, label, timer);
                    return;
                }
            };

            let region_id = basic_meta.get_region_id();
            let tablet = match tablets.get(region_id) {

View on GitHub (pinned to 78aedc1c81)

Solutions

  1. Upgrade/patch TiKV — this is an internal invariant violation; report it with the request details
  2. Inspect the request: ensure sst metadata fields required by download_request_dispatcher are populated
  3. Retry the operation; if reproducible, collect logs and file a bug
Defensive patterns

Strategy: fallback

Validate before calling

// Ensure sst metadata required by the dispatcher is populated
for m in req.get_ssts() {
    assert!(!m.get_cf().is_empty() && !m.get_sha256().is_empty());
}

Try / catch

let resp = client.batch_download(req).await?;
if let Some(err) = resp.get_error() {
    if err.get_message().contains("internal error") {
        log::error!("dispatcher invariant violated, reporting bug");
        return Err(err.into()); // escalate/upgrade TiKV
    }
    return Err(err.into());
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of tikv/tikv@78aedc1c81 (2026-09-03). Data as JSON: /api/errors/0fa80345764ab217. Report an issue: GitHub.