quickwit-oss/quickwit · error

{left:?} storage config is defined multiple times

Error message

{left:?} storage config is defined multiple times

What it means

Quickwit's storage configuration allows at most one storage definition per backend type (e.g. s3, azure, gcs, file). During validation of StorageConfigs, the backend names are sorted and adjacent pairs compared; any duplicate means the same backend was declared twice in the config, which is ambiguous. The library throws this to reject conflicting storage definitions at load time instead of guessing which one to use.

Source

Thrown at quickwit/quickwit-config/src/storage_config.rs:119

    pub fn apply_flavors(&mut self) {
        for storage_config in self.0.iter_mut() {
            if let StorageConfig::S3(s3_storage_config) = storage_config {
                s3_storage_config.apply_flavor();
            }
        }
    }

    pub fn validate(&self) -> anyhow::Result<()> {
        let backends: Vec<StorageBackend> = self
            .0
            .iter()
            .map(|storage_config| storage_config.backend())
            .sorted()
            .collect();

        for (left, right) in backends.iter().zip(backends.iter().skip(1)) {
            ensure!(
                left != right,
                "{left:?} storage config is defined multiple times",
            );
        }
        Ok(())
    }

    pub fn find_azure(&self) -> Option<&AzureStorageConfig> {
        self.0
            .iter()
            .find_map(|storage_config| match storage_config {
                StorageConfig::Azure(azure_storage_config) => Some(azure_storage_config),
                _ => None,
            })
    }

    pub fn find_google(&self) -> Option<&GoogleCloudStorageConfig> {
        self.0

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Search your quickwit config for duplicate storage blocks with the same `backend` value and remove or merge them into one.
  2. If merging config fragments, ensure each backend appears only once across all fragments.
  3. If overriding via environment variables, override the existing block's keys instead of adding a second block.

Example fix

// before (quickwit.yaml)
storage:
  s3:
    bucket: quickwit-a
  s3:
    bucket: quickwit-b
// after
storage:
  s3:
    bucket: quickwit-b
Defensive patterns

Strategy: validation

Validate before calling

fn has_duplicate_backends(cfg: &QuickwitConfig) -> bool {
    let mut backends: Vec<_> = cfg.storage_config.iter().map(|s| s.backend()).collect();
    backends.sort();
    backends.windows(2).any(|w| w[0] == w[1])
}
// if has_duplicate_backends(&cfg) { fail fast before serving }

Prevention

When it happens

Trigger: Calling StorageConfig::validate (indirectly via config loading) when the user's quickwit config defines two storage configs with the same `backend` value, e.g. two `[storage.s3]` blocks or two storage entries merged from multiple config files.

Common situations: Merging multiple config files/fragments where both define storage for the same backend; copy-pasting a storage block and forgetting to remove the original; environment-variable overrides that duplicate an existing storage section.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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