databendlabs/databend · error · InvalidInput
missing bucket in URL
Error message
missing bucket in URL
What it means
After parsing the location URL, build_operator extracts the host component as the storage bucket. For non-local schemes (anything besides file, memory, or empty), a URL without a host has no bucket to address, so the code returns InvalidInput 'missing bucket in URL'.
Solutions
- Include the bucket as the URL host in the location, e.g. 's3://my-bucket/path' instead of 's3:///path'.
- Check the variable/template that produces the location for an empty bucket value.
- Use a local scheme (file:// or memory://) only when you actually intend local/memory storage, not for remote buckets.
Example fix
// before
let location = format!("s3://{bucket}/{path}"); // bucket == ""
// after
assert!(!bucket.is_empty(), "S3 bucket must be set");
let location = format!("s3://{bucket}/{path}"); Defensive patterns
Strategy: validation
Validate before calling
let u = url::Url::parse(location)?;
if u.scheme() != "file" && u.scheme() != "memory" && u.host_str().map_or(true, str::is_empty) {
return Err(anyhow!("location {location:?} has no bucket host"));
} Try / catch
match file_io.get_operator_path(location) {
Err(e) if e.message() == "missing bucket in URL" => {
bail!("table location {location:?} must include the bucket, e.g. s3://bucket/path");
}
other => other,
} Prevention
- Check that bucket variables are non-empty before interpolating them into URIs.
- Use format!("{}://{}/{}", scheme, bucket, path) with an asserted non-empty bucket.
- Never strip the host from remote URIs when normalizing paths.
When it happens
Trigger: get_operator_path with a location like 's3:///path/to/table' or 's3://' where url::Url parses successfully but host_str() returns None (empty host).
Common situations: Table locations built by string concatenation where the bucket part was empty; environment-driven configs where a bucket variable was unset; metadata from a misconfigured catalog whose warehouse URI lost its bucket; file/memory locations mistakenly passed with a remote scheme.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- s3.access-key-id and s3.secret-access-key must be…
- s3.session-token requires s3.access-key-id and…
- {e}
- S3 params must remain S3
- value for enable_virtual_host_style is invalid
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/29701583d4f650c5.
Report an issue: GitHub.
Appendix: source
Thrown at src/common/storage/src/operator.rs:784
let scheme = url.scheme();
// Handle file:// and memory:// URIs which don't have a host/bucket
let is_local_scheme = matches!(scheme, "file" | "memory" | "");
let (bucket, relative_path_pos) = if is_local_scheme {
// For file:// URIs, the path starts after "file://"
let prefix_len = if location.starts_with("file://") {
7 // "file://".len()
} else if location.starts_with("memory://") {
9 // "memory://".len()
} else {
0
};
(None, prefix_len)
} else {
let bucket = url
.host_str()
.ok_or_else(|| Error::new(ErrorKind::InvalidInput, "missing bucket in URL"))?;
let prefix = format!("{}://{}/", scheme, bucket);
let relative_path_pos = if location.starts_with(&prefix) {
prefix.len()
} else {
url.scheme().len() + 3 + bucket.len() + 1
};
(Some(bucket), relative_path_pos)
};
let mut opendal_config: std::collections::HashMap<String, String> =
std::collections::HashMap::new();
if let Some(bucket) = bucket {
opendal_config.insert("bucket".to_string(), bucket.to_string());
}
self.validate_s3_credentials()?;
View on GitHub (pinned to 288d84d76e)