risingwavelabs/risingwave · error · SinkError::Config
gcs.service.account is required with Google Cloud Storage (G
Error message
gcs.service.account is required with Google Cloud Storage (GCS)
What it means
To open a GCS-backed DeltaLake table, the connector requires the gcs.service.account option (a service account key). If DeltaTableUrl::Gcs was detected but gcs_service_account is None, it raises SinkError::Config because the GCS handler cannot authenticate without credentials.
Source
Thrown at src/connector/src/sink/deltalake.rs:116
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)
}
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://") {View on GitHub (pinned to 6469eb736d)
Solutions
- Add the option: gcs.service.account = '<service account JSON>' to the sink's deltalake options.
- Verify the option key spelling is exactly 'gcs.service.account'.
- Ensure the provided service account JSON is valid and has access to the bucket.
Example fix
// before
CREATE SINK s INTO DELTALAKE LOCATION = 'gs://bucket/table';
// after
CREATE SINK s INTO DELTALAKE LOCATION = 'gs://bucket/table'
WITH (connector = 'deltalake', gcs.service.account = '{"type":"service_account",...}'); Defensive patterns
Strategy: validation
Validate before calling
if location.starts_with("gs://") && !options.contains_key("gcs.service.account") {
return Err("gcs.service.account is required for gs:// deltalake locations");
} Prevention
- Always include gcs.service.account with the full service account JSON for gs:// locations.
- Validate the JSON parses before creating the sink.
When it happens
Trigger: create_deltalake_client with a location starting with gs:// while the sink definition omits the 'gcs.service.account' option (it was not provided or was null).
Common situations: Creating a deltalake sink pointing at gs:// but forgetting the service account JSON; providing credentials under a wrong option name; assuming default credential chains work when the connector requires the explicit key.
Related errors
- Url parse error for GCS deltalake location (wrapped error)
- path should start with 's3://','s3a://'(s3) ,gs://(gcs) or f
- s3.access.key and s3.secret.key is required with aws s3
- total_memory_bytes {} is larger than the total memory availa
- parallelism should not be zero
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/a98d9ae102fd223b.
Report an issue: GitHub.