influxdata/influxdb · error · TableIndexError

Failed to load table index from object store

Error message

Failed to load table index from object store

What it means

TableIndexError::LoadIndex is returned when fetching the serialized table index from the object store fails with an object_store::Error. The table index maps each table to its snapshots and is read from a well-known object-store key; any GET failure (missing, network, credentials, throttling) is wrapped here. The object_store::Error is preserved as the #[source].

Solutions

  1. Check #[source] object_store::Error: if NotFound, treat as a fresh/empty index and create one rather than failing
  2. Verify object-store URL, bucket, credentials, and region in the InfluxDB3 configuration
  3. Test raw access to the index key with the same client credentials (aws s3 cp / az cli)
  4. Retry the load; transient object-store errors are common under rate limiting
  5. If the index was manually deleted, re-persist it via the writer's snapshot flow

Example fix

// before: fail hard when index object is absent
let idx = index.load().await?;
// after: treat NotFound as an empty index
let idx = match index.load().await {
    Err(e) if matches!(e, TableIndexError::LoadIndex(ref oe) if oe.not_found()) => Default::default(),
    other => other?,
};
Defensive patterns

Strategy: retry

Validate before calling

// check object-store reachability before calling load
client.head(&index_path).await?; // surfaces NotFound early so you can treat as empty index

Type guard

fn is_load_index_not_found(e: &TableIndexError) -> bool {
    matches!(e, TableIndexError::LoadIndex(oe) if oe.not_found())
}

Try / catch

match load_result {
    Err(e) if is_load_index_not_found(&e) => TableIndex::default(), // fresh start
    Err(e) if is_transient(&e) => retry_with_backoff(load, 3),
    other => other?,
}

Prevention

When it happens

Trigger: Calling CoreTableIndex/table_index load paths that issue a get() on the index object and map the Err to LoadIndex (table_index.rs ~316-328); a NotFound error on the index key also lands here.

Common situations: First startup against an empty bucket where the index has never been persisted; wrong bucket/endpoint/credentials configured for the object store; network partitions or S3 503s during reads.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/d57dd56b630c52ec. Report an issue: GitHub.

Appendix: source

Thrown at influxdb3_write/src/table_index.rs:22

use hashbrown::{HashMap, HashSet};
use object_store::ObjectStore;
use object_store_utils::RetryableObjectStore;
use observability_deps::tracing::{debug, warn};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tokio::sync::Semaphore;

use influxdb3_id::{DbId, ParquetFileId, TableId, TableIndexId};
use influxdb3_wal::SnapshotSequenceNumber;

use crate::{
    ParquetFile, PersistedSnapshot, PersistedSnapshotVersion,
    paths::{SnapshotInfoFilePath, TableIndexPath, TableIndexSnapshotPath},
};

#[derive(Debug, Error)]
pub enum TableIndexError {
    #[error("Failed to load table index from object store")]
    LoadIndex(#[source] object_store::Error),

    #[error("Failed to deserialize table index")]
    SerializeIndex(#[source] serde_json::Error),

    #[error("Failed to deserialize table index")]
    DeserializeIndex(#[source] serde_json::Error),

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

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

    #[error("Failed to load table index snapshot from object store")]
    LoadSnapshot(#[source] object_store::Error),

    #[error("Failed to deserialize table index snapshot")]

View on GitHub (pinned to 06200ef96b)