{"record":{"id":"be42dbd98a80bed7","repo":"risingwavelabs/risingwave","slug":"failed-to-check-if-table-exists","errorCode":null,"errorMessage":"Failed to check if table exists: {}","messagePattern":"Failed to check if table exists: (.+?)","errorType":"error_code","errorClass":"iceberg::Error(ErrorKind::Unexpected)","httpStatus":null,"severity":"error","filePath":"src/connector/src/connector_common/iceberg/storage_catalog.rs","lineNumber":363,"sourceCode":"    /// Drop a table from the catalog.\n    async fn drop_table(&self, table: &TableIdent) -> iceberg::Result<()> {\n        let table = self.load_table(table).await?;\n        table\n            .file_io()\n            .delete_prefix(table.metadata().location())\n            .await\n    }\n\n    async fn purge_table(&self, table: &TableIdent) -> iceberg::Result<()> {\n        self.drop_table(table).await\n    }\n\n    /// Check if a table exists in the catalog.\n    async fn table_exists(&self, table: &TableIdent) -> iceberg::Result<bool> {\n        let table_path = self.table_path(table);\n        let metadata_path = format!(\"{table_path}/metadata/version-hint.text\");\n        self.file_io.exists(&metadata_path).await.map_err(|err| {\n            Error::new(\n                ErrorKind::Unexpected,\n                format!(\"Failed to check if table exists: {}\", err.as_report()),\n            )\n        })\n    }\n\n    /// Rename a table in the catalog.\n    async fn rename_table(&self, _src: &TableIdent, _dest: &TableIdent) -> iceberg::Result<()> {\n        todo!()\n    }\n\n    /// Update a table to the catalog.\n    async fn update_table(&self, mut commit: TableCommit) -> iceberg::Result<Table> {\n        let table = self.load_table(commit.identifier()).await?;\n        let requirements = commit.take_requirements();\n        let updates = commit.take_updates();\n\n        let metadata = table.metadata().clone();","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/connector_common/iceberg/storage_catalog.rs#L345-L381","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: IAM policy missing read access on metadata prefix\n// after: allow HEAD/GET on table metadata\n{\"Effect\":\"Allow\",\"Action\":[\"s3:GetObject\",\"s3:ListBucket\"],\"Resource\":[\"arn:aws:s3:::bucket\",\"arn:aws:s3:::bucket/db/table/*\"]}","handlingStrategy":"try-catch","validationCode":"// verify storage config connectivity before catalog calls\nlet probe = file_io.exists(&format!(\"{warehouse}/probe\")).await;\nif probe.is_err() { return Err(\"object store credentials/endpoint invalid; fix config first\"); }","typeGuard":null,"tryCatchPattern":"match catalog.table_exists(&ident).await {\n    Ok(exists) => exists,\n    Err(e) => {\n        log::error!(\"storage probe failed: {e}\"); // inner report names the root cause\n        return Err(anyhow!(\"fix object-store auth/endpoint, then retry: {e}\"));\n    }\n}","preventionTips":["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"],"tags":["iceberg","storage","object-store","permissions"],"backgroundTag":"http-request-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}