databendlabs/databend · error
bendsave requires bucket but it's empty in uri
Error message
bendsave requires bucket but it's empty in uri: {} What it means
load_bendsave_storage parses a storage URI (s3://bucket/path/...). For the s3 scheme the bucket (URI authority/name) is mandatory; if it is empty the function refuses to build an Operator and returns this error. Without a bucket, opendal's S3 service cannot address any object.
Solutions
- Include the bucket in the URI authority: s3://my-bucket/path/to/root/?region=...
- Re-check the script/config that renders the URI — an empty variable is likely substituted there.
- If you intend local filesystem storage, switch the scheme to fs:// instead of s3 without a bucket.
- Run the provided test path (test_load_epochfs_storage pattern) or a dry-run with your URI to validate parsing before the real backup/restore.
Example fix
// before let uri = "s3:///backups/databend/?region=us-east-1"; // after let uri = "s3://my-bucket/backups/databend/?region=us-east-1";
Defensive patterns
Strategy: validation
Validate before calling
// Rust: validate the URI before calling backup/restore
let u = url::Url::parse(&uri)?;
if u.scheme() == "s3" && u.host_str().unwrap_or("").is_empty() {
return Err("s3 URI must include a bucket: s3://bucket/path".into());
} Try / catch
match load_bendsave_storage(&uri, ...) {
Ok(op) => op,
Err(e) if e.to_string().contains("bucket") => {
eprintln!("fix URI: s3://<bucket>/<path>?region=..."); Err(e)
}
Err(e) => Err(e),
} Prevention
- Always build storage URIs from a template that includes the bucket
- Validate URIs at config load time, not at backup time
- Keep bucket names in env/config variables with non-empty assertions
When it happens
Trigger: Calling bendsave backup or restore with a URI like s3:///path/to/root or s3:// (no bucket in the authority), or passing a URI whose name component was stripped before validation.
Common situations: Copy-pasting an internal path style URL without the bucket; environment-specific config templating that left the bucket empty; using an fs-style path with the s3 scheme.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- S3 params must remain S3
- Invalid config.rpc
- {msg}
- raft_dir of meta service must be an absolute path, but got
- Unsupported scheme
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/29384f8b6ddaebdc.
Report an issue: GitHub.
Appendix: source
Thrown at src/bendsave/src/storage.rs:197
/// Load epochfs storage from uri.
///
/// S3: `s3://bucket/path/to/root/?region=us-east-1&access_key_id=xxx&secret_access_key=xxx`
/// Fs: `fs://path/to/data`
pub async fn load_bendsave_storage(uri: &str) -> Result<Operator> {
let uri = http::Uri::from_str(uri)?;
let scheme = uri.scheme_str().unwrap_or_default();
let name = uri.host().unwrap_or_default();
let path = uri.path();
let mut map: HashMap<String, String> =
form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes())
.map(|(k, v)| (k.to_string(), v.to_lowercase()))
.collect();
let op = match scheme {
"s3" => {
if name.is_empty() {
return Err(anyhow!(
"bendsave requires bucket but it's empty in uri: {}",
uri.to_string()
));
}
map.insert("bucket".to_string(), name.to_string());
map.insert("root".to_string(), path.to_string());
let op = Operator::from_iter::<opendal::services::S3>(map)?.finish();
Ok(op)
}
"fs" => {
map.insert("root".to_string(), format!("/{name}/{path}"));
let op = Operator::from_iter::<opendal::services::Fs>(map)?.finish();
Ok(op)
}
_ => Err(anyhow::anyhow!("Unsupported scheme: {}", scheme)),
}?;
let op = opView on GitHub (pinned to 288d84d76e)