tikv/tikv · error

{}

Error message

{}

What it means

The private helper `fn err<S: Display>(s: S) -> StorageError` in endpoint.rs builds a `StorageError` from an arbitrary displayable value via `anyhow!("{}", s)`. It is the endpoint module's convenience constructor for ad-hoc storage errors with a formatted message; the message itself is whatever string the caller formats.

Source

Thrown at src/coprocessor/endpoint.rs:1284

            && !pb_ctx.get_stale_read()
            && !pb_ctx.get_replica_read()
        {
            // Some scenes are not supported before an effective argument, including:
            // - stale-read & replica-read, TODO: support it later
            // - non-SI isolation level, TODO: support it later
            return Some(Self {
                store_id,
                req_ctx,
                concurrency_manager,
                _phantom: PhantomData,
            });
        }
        None
    }

    #[inline]
    fn err<S: Display>(s: S) -> StorageError {
        StorageError::from(anyhow!("{}", s))
    }
}

#[async_trait]
impl<E: Engine> RegionStorageAccessor for ExtraSnapStoreAccessor<E> {
    type Storage = SnapshotStore<E::IMSnap>;

    /// find the region by the specified key.
    /// The argument `key` should be the comparable format, you should use
    /// `Key::from_raw` encode the raw key.
    async fn find_region_by_key(&self, key: &[u8]) -> StorageResult<FindRegionResult> {
        let key_in_vec = key.to_vec();
        let (tx, rx) = oneshot::channel();
        unsafe {
            with_tls_engine(|engine: &mut E| -> StorageResult<()> {
                engine
                    .seek_region(
                        key,

View on GitHub (pinned to 78aedc1c81)

Solutions

  1. Read the formatted message in the error to determine which endpoint step failed.
  2. Verify snapshot availability / region epoch freshness at the caller that produced the Display'd reason.
  3. Retry the coprocessor request after the region cache refreshes if the cause was an epoch mismatch.
  4. If the message is a transient storage issue, check RocksDB/raftstore health.

Example fix

// before
let se = err(format!("no snapshot for region {}", region_id));
// after
let se = err(format!("no snapshot for region {}, epoch {:?}; check region cache", region_id, epoch));
Defensive patterns

Strategy: try-catch

Type guard

fn storage_err_message(e: &tidb_query_common::error::Error) -> String {
    match e {
        tidb_query_common::error::Error::StorageError(se) => se.to_string(),
        other => other.to_string(),
    }
}

Try / catch

match endpoint_result {
    Err(e) if e.to_string().contains("no snapshot") => {
        // snapshot gone: refresh region/snapshot and retry
    }
    Err(e) => return Err(e),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: Any call site inside the coprocessor Endpoint that invokes `err(...)` (or formats a message the same way) to convert a failure description into a `StorageError`, e.g. wrapping snapshot accessor or region lookup failures with a Display'd reason.

Common situations: Region snapshot creation failures, missing snapshots in the endpoint's extra-snapshot accessor (`ExtraSnapStoreAccessor`), or any code path needing a quick anyhow-backed StorageError from a Display value such as a region ID or key range.

Related errors


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