risingwavelabs/risingwave · error · SinkError::DeltaLake
path should start with 's3://','s3a://'(s3) ,gs://(gcs) or f
Error message
path should start with 's3://','s3a://'(s3) ,gs://(gcs) or file://(local)
What it means
get_table_url classifies the deltalake location by prefix into S3 (s3://, s3a://), GCS (gs://) or Local (file://). A location with none of these prefixes cannot be routed to a storage handler, so it raises SinkError::DeltaLake listing the accepted schemes.
Source
Thrown at src/connector/src/sink/deltalake.rs:137
})?,
);
deltalake::gcp::register_handlers(None);
let url = Url::parse(&gcs_path).map_err(|e| SinkError::DeltaLake(anyhow!(e)))?;
deltalake::open_table_with_storage_options(url, storage_options).await?
}
};
Ok(table)
}
fn get_table_url(path: &str) -> Result<DeltaTableUrl> {
if path.starts_with("s3://") || path.starts_with("s3a://") {
Ok(DeltaTableUrl::S3(path.to_owned()))
} else if path.starts_with("gs://") {
Ok(DeltaTableUrl::Gcs(path.to_owned()))
} else if let Some(path) = path.strip_prefix("file://") {
Ok(DeltaTableUrl::Local(path.to_owned()))
} else {
Err(SinkError::DeltaLake(anyhow!(
"path should start with 's3://','s3a://'(s3) ,gs://(gcs) or file://(local)"
)))
}
}
async fn build_delta_lake_config_for_aws(&self) -> Result<HashMap<String, String>> {
let mut storage_options = HashMap::new();
storage_options.insert(AWS_ALLOW_HTTP.to_owned(), "true".to_owned());
storage_options.insert(AWS_S3_ALLOW_UNSAFE_RENAME.to_owned(), "true".to_owned());
let sdk_config = self.aws_auth_props.build_config().await?;
let credentials = sdk_config
.credentials_provider()
.ok_or_else(|| {
SinkError::Config(anyhow!(
"s3.access.key and s3.secret.key is required with aws s3"
))
})?
.as_ref()View on GitHub (pinned to 6469eb736d)
Solutions
- Prefix local paths with file:// (e.g. file:///absolute/path).
- Use s3:// or s3a:// for AWS S3 locations and gs:// for GCS locations.
- Check the configured location value for typos or a missing scheme; Azure/other backends are not supported here.
Example fix
// before LOCATION = '/data/delta_table' // after LOCATION = 'file:///data/delta_table'
Defensive patterns
Strategy: validation
Validate before calling
const SCHEMES: [&str; 4] = ["s3://", "s3a://", "gs://", "file://"];
if !SCHEMES.iter().any(|s| location.starts_with(s)) {
return Err(format!("deltalake location must start with one of {:?}", SCHEMES));
} Prevention
- Always specify an explicit supported scheme (s3://, s3a://, gs://, file://) in the location.
- Remember bare local paths are rejected — prefix with file://.
- Validate location scheme at DDL time before deploying the sink.
When it happens
Trigger: create_deltalake_client calls get_table_url with a location lacking any recognized prefix — e.g. '/local/path' without file://, 'https://...', 'abfs://...', or an empty string.
Common situations: Passing a bare local path instead of file:///path; using an Azure Blob or other unsupported scheme; empty or mistyped location option.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- Url parse error for S3 deltalake location (wrapped error)
- Url parse error for local deltalake location (wrapped error)
- gcs.service.account is required with Google Cloud Storage (G
- Url parse error for GCS deltalake location (wrapped error)
- Can't get fe host from url
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/c1f43e0d284d96ba.
Report an issue: GitHub.