risingwavelabs/risingwave · error · SinkError::DeltaLake

Url parse error for local deltalake location (wrapped error)

Error message

Url parse error for local deltalake location (wrapped error)

What it means

For a local filesystem DeltaLake table, the connector prefixes the stripped local path with 'file://' and parses it into a `Url`. A Url::parse failure is wrapped in SinkError::DeltaLake. This is rare because file:// URLs parse easily, but can occur with odd path contents.

Source

Thrown at src/connector/src/sink/deltalake.rs:108

            .into());
        }

        Ok(())
    }
}

impl DeltaLakeCommon {
    pub async fn create_deltalake_client(&self) -> Result<DeltaTable> {
        let table = match Self::get_table_url(&self.location)? {
            DeltaTableUrl::S3(s3_path) => {
                let storage_options = self.build_delta_lake_config_for_aws().await?;
                deltalake::aws::register_handlers(None);
                let url = Url::parse(&s3_path).map_err(|e| SinkError::DeltaLake(anyhow!(e)))?;
                deltalake::open_table_with_storage_options(url, storage_options).await?
            }
            DeltaTableUrl::Local(local_path) => {
                let url = Url::parse(&format!("file://{}", local_path))
                    .map_err(|e| SinkError::DeltaLake(anyhow!(e)))?;
                deltalake::open_table(url).await?
            }
            DeltaTableUrl::Gcs(gcs_path) => {
                let mut storage_options = HashMap::new();
                storage_options.insert(
                    GCS_SERVICE_ACCOUNT.to_owned(),
                    self.gcs_service_account.clone().ok_or_else(|| {
                        SinkError::Config(anyhow!(
                            "gcs.service.account is required with Google Cloud Storage (GCS)"
                        ))
                    })?,
                );
                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)

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Provide a plain absolute path or a valid file:// URL without stray percent signs.
  2. Percent-encode special characters properly (e.g. %25 for a literal %).
  3. Remove control characters/whitespace from the configured location.

Example fix

// before
LOCATION = 'file:///data/tabl%zz'
// after
LOCATION = 'file:///data/table%25data'
Defensive patterns

Strategy: validation

Validate before calling

let loc = location.trim();
if !loc.starts_with("file://") {
    return Err("local deltalake location must start with file://");
}
Url::parse(loc).map_err(|e| format!("invalid file URL: {e}"))?;

Prevention

When it happens

Trigger: create_deltalake_client with DeltaTableUrl::Local whose path (after stripping 'file://') fails Url::parse when re-wrapped as file://{path} — e.g. path containing control characters or malformed percent-encodings like '%zz'.

Common situations: Paths containing stray percent signs or broken percent-encoding ('%zz') or control characters copied from elsewhere; Windows-style or otherwise unusual paths pasted into the location option.

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/31a5233e84f4ae8f. Report an issue: GitHub.