quickwit-oss/quickwit · error
storage factory and config backends should match
Error message
storage factory and config backends should match
What it means
This panic is thrown by `StorageResolver::configured` after building the storage resolver from the set of storage backends compiled into the binary. It means the internal invariant that every `StorageBackend` variant declared in the configuration (File, S3, Azure, Google) has a corresponding registered storage factory was violated. Since the resolver builder registers a factory for every backend enabled by cargo features (the code right above panics on backends missing their feature), this can only fire if a new backend variant was added to `StorageBackend` without registering a factory, or feature/build wiring diverged. It is an assertion of compile-time/feature consistency, not a runtime misconfiguration the user can cause.
Source
Thrown at quickwit/quickwit-storage/src/storage_resolver.rs:134
}
#[cfg(feature = "gcs")]
{
builder = builder.register(GoogleCloudStorageFactory::new(
storage_configs.find_google().cloned().unwrap_or_default(),
));
}
#[cfg(not(feature = "gcs"))]
{
use crate::storage_factory::UnsupportedStorage;
builder = builder.register(UnsupportedStorage::new(
StorageBackend::Google,
"Quickwit was compiled without the `gcs` feature",
))
}
builder
.build()
.expect("storage factory and config backends should match")
}
/// Returns a [`StorageResolver`] for testing purposes. Unlike
/// [`StorageResolver::unconfigured`], this resolver does not return a singleton.
#[cfg(any(test, feature = "testsuite"))]
pub fn for_test() -> Self {
StorageResolver::builder()
.register(RamStorageFactory::default())
.register(LocalFileStorageFactory)
.build()
.expect("storage factory and config backends should match")
}
}
#[derive(Default)]
pub struct StorageResolverBuilder {
per_backend_factories: HashMap<StorageBackend, Box<dyn StorageFactory>>,
}View on GitHub (pinned to a39730c5cd)
Solutions
- Check the cargo features used to build Quickwit: rebuild with the feature matching your config backend enabled (e.g. `gcs` for StorageBackend::Google) — the preceding expect already guards this, so if you hit this one your build is inconsistent
- If you added a new `StorageBackend` variant, register a corresponding factory in the `StorageResolver::configured` builder in quickwit/quickwit-storage/src/storage_resolver.rs
- Rebuild from a clean checkout of an unmodified Quickwit release; a patched or stale build is the usual cause
- If it reproduces on unmodified code, file a bug — this is an internal invariant violation
Example fix
// before (new backend variant added without factory)
StorageBackend::MyNewBackend => unreachable!()
// after
builder = builder.register(
StorageBackend::MyNewBackend,
StorageFactoryUri::try_new("mynewbackend")?,
Arc::new(MyNewBackendFactory::default()),
); Defensive patterns
Strategy: validation
Validate before calling
// Before relying on a configured resolver, check the backend you need is registered
let resolver = StorageResolver::configured(&storage_configs)?; // prefer ?-propagation upstream; if you must call expect paths, verify feature gates first
assert!(
cfg!(feature = "gcs") || storage_configs.google.is_none(),
"gcs config present but binary compiled without gcs feature"
); Prevention
- When adding a StorageBackend variant, immediately register its factory in StorageResolver::configured and add a unit test that resolves every backend
- Build with the full set of storage features (`--all-features`) in CI to surface unregistered backends
- Never patch the StorageBackend enum in forks without updating the resolver builder
When it happens
Trigger: Calling `StorageResolver::configured(...)` when the resolver builder's registry does not contain a factory for every `StorageBackend` variant derivable from config — e.g. the binary was built so a config-visible backend (like `gcs`) is absent and the earlier `expect` did not cover it, or a contributor added a new `StorageBackend` variant without adding it to the builder in `configured`.
Common situations: A developer adds support for a new storage backend to the `StorageBackend` enum but forgets to register its factory in `configured`; a custom build with unusual feature flags leaves a backend enum variant unregistered; downstream forks patching the enum or feature gates.
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
- `append_records` should be called with `position_opt: None`
- failed to run mrecordlog operation
- stdin cannot be checkpointed
- Unexpected span kind: {}
- missing file `{}` in split bundle
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/c9ca76fc56f8bfa9.
Report an issue: GitHub.