dani-garcia/vaultwarden · error · opendal::Error
ConfigInvalid
ConfigInvalid
Error message
S3 support is not enabled
What it means
operator_for_path() builds and caches an opendal operator for a storage path. Paths starting with s3:// require the compile-time cargo feature s3 (opendal services-s3 plus AWS credential crates; the default feature set in Cargo.toml is empty, so s3 is opt-in). On a binary built without it, the #[cfg(not(s3))] arm returns opendal ErrorKind::ConfigInvalid 'S3 support is not enabled', which surfaces as an error on the first operation that touches that path (attachment/Send read or write).
Source
Thrown at src/storage.rs:64
std::path::Path::new(path).file_name()?.to_str().map(str::to_owned)
}
pub(crate) fn is_fs_operator(operator: &opendal::Operator) -> bool {
operator.info().scheme() == opendal::services::FS_SCHEME
}
pub(crate) fn operator_for_path(path: &str) -> Result<opendal::Operator, crate::Error> {
// Cache of previously built operators by path
static OPERATORS_BY_PATH: LazyLock<dashmap::DashMap<String, opendal::Operator>> =
LazyLock::new(dashmap::DashMap::new);
if let Some(operator) = OPERATORS_BY_PATH.get(path) {
return Ok(operator.clone());
}
let operator = if path.starts_with("s3://") {
#[cfg(not(s3))]
return Err(opendal::Error::new(opendal::ErrorKind::ConfigInvalid, "S3 support is not enabled").into());
#[cfg(s3)]
s3::operator_for_path(path)?
} else {
let builder = opendal::services::Fs::default().root(path);
opendal::Operator::new(builder)?
};
OPERATORS_BY_PATH.insert(path.to_owned(), operator.clone());
Ok(operator)
}
#[cfg(s3)]
mod s3 {
use reqwest::Url;
use crate::error::Error;View on GitHub (pinned to 0cefa4cca7)
Solutions
- Rebuild with the feature: cargo build --release --no-default-features --features sqlite,s3 (add your DB backend)
- Or switch to an image/binary explicitly built with the s3 feature
- Or revert to local storage: DATA_FOLDER=/data
- Verify the build's feature list before configuring s3:// paths
Example fix
# before DATA_FOLDER=s3://mybucket/vw-data # after (option A: local storage) DATA_FOLDER=/data # after (option B: build with s3) cargo build --release --no-default-features --features sqlite,s3
Defensive patterns
Strategy: validation
Validate before calling
# Before pointing storage at S3, confirm this binary has the s3 feature compiled in
BIN="$(command -v vaultwarden)"
if [[ "${DATA_FOLDER:-}" == s3://* ]] && ! strings "$BIN" | grep -q reqsign; then
echo "FATAL: DATA_FOLDER uses s3:// but this build lacks the 's3' cargo feature" >&2
exit 1
fi Type guard
// Compile-time feature probe usable inside the codebase const S3_FEATURE_ENABLED: bool = cfg!(s3);
Prevention
- Decide the storage backend before deployment and build the matching feature set
- Keep DATA_FOLDER on a local volume unless the build explicitly includes s3
- Record the cargo features used in deployment notes or image labels
- Test one attachment upload after switching storage backends
When it happens
Trigger: Setting DATA_FOLDER (or another storage dir such as ATTACHMENTS_FOLDER) to an s3://bucket/... URL while the running binary was compiled without --features s3; the failure appears lazily on the first storage operation, not at startup.
Common situations: Using a stock binary or distro package and pointing storage at S3; building from source with default features; upgrading to a build that dropped the s3 feature.
Related errors
- Failed to parse global log level
- Failed to parse overrides
- Can't convert to number
- Error saving API key
- Error saving attachment
AI-assisted analysis of dani-garcia/vaultwarden@0cefa4cca7 (2026-08-16).
Data as JSON: /api/errors/395d8a0029815dd8.
Report an issue: GitHub.