databendlabs/databend · error

input path is not a valid glob

Error message

input path is not a valid glob: {err:?}

What it means

This error is raised when parsing the `path` portion of a storage LOCATION URI as a glob pattern fails (`globiter::Pattern::parse`). Databend uses the parsed glob to enumerate matching object keys, so an unparseable pattern makes the location unusable. The underlying glob parse error is attached via `anyhow!` with debug formatting.

Solutions

  1. Fix the glob syntax in the location path: balance brackets `[...]`, validate ranges like `[a-z]`, and escape literal `[`/`*` characters if they are meant literally.
  2. Test the path with a glob library (or the globiter crate) locally before putting it into the DDL statement.
  3. If a literal path (no globbing) is intended, ensure it contains no glob metacharacters at all.
  4. Read the debug-formatted `err` in the message; it names the exact offset/reason the pattern failed.

Example fix

// before
'azblob://container/reports[2024/file.csv'
// after
'azblob://container/reports\\[2024\\]/file.csv'  (escaped literals) or 'azblob://container/reports/file.csv'
Defensive patterns

Strategy: validation

Validate before calling

fn validate_glob(path: &str) -> Result<(), String> {
    globiter::Pattern::parse(path)
        .map(|_| ())
        .map_err(|e| format!("invalid glob {:?}: {:?}", path, e))
}

Prevention

When it happens

Trigger: Calling a stage/table-location binder with a URI whose path component contains malformed glob syntax — e.g. unterminated `[`, unmatched `*`/`**` misuse, or invalid character-class ranges — via `StorageHttpConfig` construction from a parsed location.

Common situations: Typos in COPY INTO / external location strings like `s3://bucket/data/[tmp]/x.csv`, brackets used literally without escaping, or paths copied from templates with unresolved placeholders (`{date}` with bad syntax).

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/39dbba0fbbba5484. Report an issue: GitHub.

Appendix: source

Thrown at src/query/sql/src/planner/binder/location.rs:615

    let sp = match protocol {
        Scheme::Azblob => parse_azure_params(l, root)?,
        Scheme::Gcs => parse_gcs_params(l, root)?,
        #[cfg(feature = "storage-hdfs")]
        Scheme::Hdfs => parse_hdfs_params(l, root)?,
        Scheme::Ipfs => parse_ipfs_params(l, root)?,
        Scheme::S3 => parse_s3_params(l, root)?,
        Scheme::Obs => parse_obs_params(l, root)?,
        Scheme::Oss => parse_oss_params(l, root)?,
        Scheme::Cos => parse_cos_params(l, root)?,
        Scheme::Http => {
            // Make sure path has been percent decoded before parse pattern.
            let cfg = StorageHttpConfig {
                endpoint_url: format!("{}://{}", l.protocol, l.name),
                paths: globiter::Pattern::parse(&l.path)
                    .map_err(|err| {
                        Error::new(
                            ErrorKind::InvalidInput,
                            anyhow!("input path is not a valid glob: {err:?}"),
                        )
                    })?
                    .iter()
                    .collect(),
                network_config: None,
            };

            // HTTP is special that we don't support dir, always return / instead.
            check_storage_params_endpoints(&StorageParams::Http(cfg.clone()))
                .await
                .map_err(|err| Error::new(ErrorKind::InvalidInput, err.to_string()))?;
            return Ok((StorageParams::Http(cfg), "/".to_string()));
        }
        Scheme::Fs => {
            if root == "/" && path == STDIN_FD {
                StorageParams::Memory
            } else {
                let cfg = StorageFsConfig { root };

View on GitHub (pinned to 288d84d76e)