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

  1. Include the bucket as the URL host in the location, e.g. 's3://my-bucket/path' instead of 's3:///path'.
  2. Check the variable/template that produces the location for an empty bucket value.
  3. 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

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


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)