risingwavelabs/risingwave · error

s3 url {location} should have a '/' at the start of path.

Error message

s3 url {location} should have a '/' at the start of path.

What it means

Raised by `load_file_descriptor_from_s3` in aws_utils.rs when an S3 location URL's path component does not start with '/'. The code strips the leading '/' from `url.path()` to derive the object key; `strip_prefix('/')` returning None means the URL was malformed (no root path), so the S3 GET would use an invalid key.

Source

Thrown at src/connector/src/aws_utils.rs:117

            .build()
    } else {
        s3_config::Config::new(sdk_config)
    };
    s3_client::Client::from_conf(s3_config_obj)
}

// TODO(Tao): Probably we should never allow to use S3 URI.
pub async fn load_file_descriptor_from_s3(
    location: &Url,
    config: &AwsAuthProps,
) -> ConnectorResult<Vec<u8>> {
    let bucket = location
        .domain()
        .with_context(|| format!("illegal file path {}", location))?;
    let key = location
        .path()
        .strip_prefix('/')
        .ok_or_else(|| anyhow!("s3 url {location} should have a '/' at the start of path."))?;
    let sdk_config = config.build_config().await?;
    let s3_client = s3_client(&sdk_config, Some(default_conn_config()));
    let response = s3_client
        .get_object()
        .bucket(bucket.to_owned())
        .key(key)
        .send()
        .await
        .with_context(|| format!("failed to get file from s3 at `{}`", location))?;

    let body = response
        .body
        .collect()
        .await
        .with_context(|| format!("failed to read file from s3 at `{}`", location))?;
    Ok(body.into_bytes().to_vec())
}

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Include the object key with a leading slash in the location, e.g. `s3://bucket/path/to/file.json`.
  2. If listing bucket contents is intended, use `s3://bucket/` with the trailing slash.
  3. Validate the URL shape before passing it to S3-loading APIs.

Example fix

// before
let url = "s3://my-bucket";
// after
let url = "s3://my-bucket/credentials.json";
Defensive patterns

Strategy: validation

Validate before calling

function validateS3Url(u) {
  const url = new URL(u);
  if (url.protocol !== 's3:') throw new Error('not an s3 url');
  if (!url.pathname.startsWith('/') || url.pathname.length < 2) {
    throw new Error(`s3 url ${u} must include a key path like s3://bucket/key`);
  }
}
validateS3Url('s3://my-bucket/creds.json');

Try / catch

try { const bytes = await bytesFromUrl(loc); } catch (e) { if (String(e).includes("should have a '/' at the start of path")) throw new Error(`Malformed S3 location '${loc}': include the object key, e.g. s3://bucket/key`); throw e; }

Prevention

When it happens

Trigger: Passing an S3 location like `s3://bucket` (no trailing slash/path) or a URL whose path lacks the leading slash into functions that call `load_file_descriptor_from_s3` such as `bytes_from_url` or `get_auth_json_from_path`.

Common situations: Typing `s3://mybucket` instead of `s3://mybucket/key` in a source/secret file path config; building the URL programmatically and forgetting the path segment.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/ae87fcab1f7f88f8. Report an issue: GitHub.