quickwit-oss/quickwit · error · anyhow::Error

index `{}` not found

Error message

index `{}` not found

What it means

The control-plane in-memory model maintains an `index_table` of known indexes. `update_index_config` replaces an index's config only when the index already exists; if the `IndexUid` is absent from the table it bails with "index not found" rather than silently creating it.

Source

Thrown at quickwit/quickwit-control-plane/src/model/mod.rs:215

        for (source_id, source_config) in &index_metadata.sources {
            if source_config.source_type() == SourceType::IngestV2 {
                self.shard_table.add_source(&index_uid, source_id);
            }
        }
        self.index_table.insert(index_uid, index_metadata);
        self.update_metrics();
    }

    /// Updates the configuration of the specified index, returning an error if
    /// the index didn't exist.
    pub(crate) fn update_index_config(
        &mut self,
        index_uid: &IndexUid,
        index_config: IndexConfig,
    ) -> anyhow::Result<bool> {
        let Some(index_model) = self.index_table.get_mut(index_uid) else {
            bail!("index `{}` not found", index_uid.index_id);
        };
        let fp_changed = !index_model.index_config.equals_fingerprint(&index_config);
        index_model.index_config = index_config;
        Ok(fp_changed)
    }

    pub(crate) fn delete_index(&mut self, index_uid: &IndexUid) {
        self.index_table.remove(index_uid);
        self.index_uid_table.remove(&index_uid.index_id);
        self.shard_table.delete_index(&index_uid.index_id);
        self.update_metrics();
    }

    /// Adds a source to a given index. Returns an error if the source already
    /// exists.
    pub(crate) fn add_source(
        &mut self,
        index_uid: &IndexUid,

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Ensure the index exists first (create-index flow populated the model) before sending index config updates.
  2. Verify the IndexUid (index_id + generation) matches the one returned by index creation, not a rebuilt/stale one.
  3. Restore control plane state (metastore-backed recovery) before processing queued update messages.

Example fix

// before
model.update_index_config(&unknown_uid, config)?;
// after
if model.index_table().contains_key(&unknown_uid) {
    model.update_index_config(&unknown_uid, config)?;
} else {
    return Err(anyhow!("index {} must be created before update", unknown_uid.index_id));
}
Defensive patterns

Strategy: validation

Validate before calling

// Rust: check existence before update
if !model.index_table().contains_key(&index_uid) {
    return Err(anyhow::anyhow!("cannot update config: index {} not registered", index_uid.index_id));
}

Try / catch

match model.update_index_config(&index_uid, config) {
    Ok(changed) => {/* apply */},
    Err(e) if e.to_string().contains("not found") => {
        // re-sync model state from metastore before retrying
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `ControlPlaneModel::update_index_config` with an `IndexUid` that was never added via index creation, or that was deleted, or that belongs to a control plane that lost its state and is replaying stale update messages.

Common situations: Control plane restarted from empty state receiving index-config update messages out of order; an index was deleted between the create and the update; tests exercising the model with a fabricated IndexUid.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/85ef28b5855785b0. Report an issue: GitHub.