risingwavelabs/risingwave · error · iceberg::Error(ErrorKind::Unexpected)
Failed to check if table exists: {}
Error message
Failed to check if table exists: {} What it means
table_exists checks for `{table_path}/metadata/version-hint.text` via file_io.exists. This error is thrown when that existence probe itself fails (as opposed to returning false), wrapping the underlying object-store error with the table context.
Source
Thrown at src/connector/src/connector_common/iceberg/storage_catalog.rs:363
/// Drop a table from the catalog.
async fn drop_table(&self, table: &TableIdent) -> iceberg::Result<()> {
let table = self.load_table(table).await?;
table
.file_io()
.delete_prefix(table.metadata().location())
.await
}
async fn purge_table(&self, table: &TableIdent) -> iceberg::Result<()> {
self.drop_table(table).await
}
/// Check if a table exists in the catalog.
async fn table_exists(&self, table: &TableIdent) -> iceberg::Result<bool> {
let table_path = self.table_path(table);
let metadata_path = format!("{table_path}/metadata/version-hint.text");
self.file_io.exists(&metadata_path).await.map_err(|err| {
Error::new(
ErrorKind::Unexpected,
format!("Failed to check if table exists: {}", err.as_report()),
)
})
}
/// Rename a table in the catalog.
async fn rename_table(&self, _src: &TableIdent, _dest: &TableIdent) -> iceberg::Result<()> {
todo!()
}
/// Update a table to the catalog.
async fn update_table(&self, mut commit: TableCommit) -> iceberg::Result<Table> {
let table = self.load_table(commit.identifier()).await?;
let requirements = commit.take_requirements();
let updates = commit.take_updates();
let metadata = table.metadata().clone();View on GitHub (pinned to 6469eb736d)
Solutions
- Read the wrapped cause (`{}` contains err.as_report()) and fix the root storage error it reports.
- Verify storage credentials, region, and endpoint configuration for the catalog.
- Grant the principal read/HEAD permission on the table's `metadata/` prefix.
- Confirm network reachability to the object store from the RisingWave/connector host.
Example fix
// before: IAM policy missing read access on metadata prefix
// after: allow HEAD/GET on table metadata
{"Effect":"Allow","Action":["s3:GetObject","s3:ListBucket"],"Resource":["arn:aws:s3:::bucket","arn:aws:s3:::bucket/db/table/*"]} Defensive patterns
Strategy: try-catch
Validate before calling
// verify storage config connectivity before catalog calls
let probe = file_io.exists(&format!("{warehouse}/probe")).await;
if probe.is_err() { return Err("object store credentials/endpoint invalid; fix config first"); } Try / catch
match catalog.table_exists(&ident).await {
Ok(exists) => exists,
Err(e) => {
log::error!("storage probe failed: {e}"); // inner report names the root cause
return Err(anyhow!("fix object-store auth/endpoint, then retry: {e}"));
}
} Prevention
- Validate S3/GCS/Azure region, endpoint, and credentials at startup
- Ensure IAM policies include HEAD/GET on the metadata prefix
- Alert on object-store error rates from connector logs
When it happens
Trigger: Any table_exists call where the storage backend errors on HEAD of the version-hint path: invalid or expired credentials, missing HeadObject/GetProperties permission, DNS/endpoint misconfiguration, storage service outage.
Common situations: Wrong S3 region or endpoint in catalog config; IAM policy lacking s3:ListBucket/GetObject on the metadata prefix; credentials not propagated to the connector; proxy/firewall blocking the object store.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- check if version hint exist failed: {}
- Fail to check exist
- Storage error: {0}
- Fail to convert version_hint from utf8 to string: {}
- parse version hint failed
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/be42dbd98a80bed7.
Report an issue: GitHub.