influxdata/influxdb · error · TableIndexCacheError

Unexpected error

Error message

Unexpected error

What it means

TableIndexCacheError::Unexpected wraps an anyhow::Error for failures that do not fit the enumerated variants, e.g. persisting an updated index during purge_expired reports "Failed to persist updated table index" through this variant. It is a catch-all indicating an unclassified internal failure while maintaining table indexes.

Solutions

  1. Read the anyhow message plus the #[source] chain to identify the real underlying failure and address that root cause.
  2. If it is an object store I/O problem, verify store health, credentials, and network as for the ObjectStore variant.
  3. If it occurs during retention/purge, retry the purge operation once the store is healthy; the index persist is idempotent per cutoff.
  4. Consider improving the code to map the inner error to a typed variant instead of anyhow for better diagnostics.

Example fix

// before
.map_err(|e| TableIndexCacheError::Unexpected(anyhow::anyhow!("Failed to persist updated table index: {:?}", e)))?
// after
.map_err(TableIndexCacheError::SplitPersistedSnapshotError)?
Defensive patterns

Strategy: try-catch

Type guard

fn is_unexpected(e: &TableIndexCacheError) -> Option<&anyhow::Error> {
    match e { TableIndexCacheError::Unexpected(a) => Some(a), _ => None }
}

Try / catch

match cache.purge_expired(node, db, table, cutoff).await {
    Err(e) if is_unexpected(&e).is_some() => {
        error!("unclassified table index failure: {:?}", e);
        alert_and_retry().await
    }
    r => r?,
}

Prevention

When it happens

Trigger: purge_expired's call to CoreTableIndex::persist fails and is converted via anyhow::anyhow! into TableIndexCacheError::Unexpected (table_index_cache.rs:937-942); other ad-hoc internal error paths also use this variant.

Common situations: Any underlying TableIndexError (object store I/O, JSON) surfacing from an index persist during retention/hard-delete operations, or genuinely unforeseen internal states — the wrapped message and source chain name the real cause.

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 influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/1b136283e0f3c51f. Report an issue: GitHub.

Appendix: source

Thrown at influxdb3_write/src/table_index_cache.rs:57

#[derive(Debug, Error)]
pub enum TableIndexCacheError {
    #[error("Object store operation failed")]
    ObjectStore(#[source] object_store::Error),

    #[error("JSON serialization/deserialization failed")]
    Json(#[source] serde_json::Error),

    #[error("TableIndex operation failed")]
    TableIndex(#[source] crate::table_index::TableIndexError),

    #[error("Object meta is missing filename")]
    MissingFilename,

    #[error("Failed to parse snapshot sequence number from filename")]
    InvalidSnapshotSequenceNumber,

    #[error("Unexpected error")]
    Unexpected(#[source] anyhow::Error),

    #[error("Table snapshot persistence task failed")]
    TableSnapshotPersistenceTaskFailed(#[source] tokio::task::JoinError),

    #[error("Failed to list table indices from object store")]
    ListIndices(#[source] object_store::Error),

    #[error("Failed to parse table index path from object store path")]
    TableIndexPath(#[source] crate::paths::PathError),

    #[error("Failed to list table index snapshots from object store")]
    ListSnapshots(#[source] object_store::Error),

    #[error("Failed to parse table index snapshot path from object store path")]
    TableIndexSnapshotPath(#[source] crate::paths::PathError),

    #[error("Failed to update table index: join task failed")]

View on GitHub (pinned to 06200ef96b)