{"record":{"id":"718f9030a0e60e4a","repo":"risingwavelabs/risingwave","slug":"no-version-hint-found-for-table","errorCode":null,"errorMessage":"no version hint found for table","messagePattern":"no version hint found for table","errorType":"error_code","errorClass":"iceberg::Error(ErrorKind::DataInvalid)","httpStatus":null,"severity":"error","filePath":"src/connector/src/connector_common/iceberg/storage_catalog.rs","lineNumber":194,"sourceCode":"    pub fn file_io(&self) -> &FileIO {\n        &self.file_io\n    }\n\n    fn table_path(&self, table: &TableIdent) -> String {\n        let mut names = table.namespace.clone().inner();\n        names.push(table.name.clone());\n        if self.warehouse.ends_with('/') {\n            format!(\"{}{}\", self.warehouse, names.join(\"/\"))\n        } else {\n            format!(\"{}/{}\", self.warehouse, names.join(\"/\"))\n        }\n    }\n\n    async fn commit_table(&self, table_path: &str, next_metadata: TableMetadata) -> Result<()> {\n        let current_version = if self.is_version_hint_exist(table_path).await? {\n            self.read_version_hint(table_path).await?\n        } else {\n            return Err(Error::new(\n                ErrorKind::DataInvalid,\n                \"no version hint found for table\",\n            ));\n        };\n\n        // # NOTE\n        // Iceberg rust didn't support rename operation now, so this commit operation is not atomic.\n        let final_metadata_file_path = format!(\n            \"{table_path}/metadata/v{}.metadata.json\",\n            current_version + 1\n        );\n        self.file_io()\n            .new_output(final_metadata_file_path)?\n            .write(serde_json::to_string(&next_metadata)?.into())\n            .await?;\n\n        // write version hint\n        let final_file_path = format!(\"{table_path}/metadata/version-hint.text\");","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/connector_common/iceberg/storage_catalog.rs#L176-L212","documentation":"During commit_table, the storage catalog only writes a new metadata version if a `version-hint.text` file already exists for the table. If it does not exist, the catalog refuses to commit because it cannot determine the current version, treating the table as unknown or uninitialized in this catalog.","triggerScenarios":"Calling update_table on a table whose `{table_path}/metadata/version-hint.text` is missing — e.g. the table was created by another catalog (Hive/REST/Nessie), the metadata folder was deleted, or the table path is wrong.","commonSituations":"Pointing RisingWave at a table managed by an external Iceberg catalog; version-hint file removed by a retention/lifecycle rule on the object store; typo in the table identifier/path; table registered in metadata but never committed via the storage catalog.","solutions":["Verify `{table_path}/metadata/version-hint.text` exists and is readable with your storage credentials; fix the table path if it was mistyped.","If the table is managed by another catalog, configure that catalog (Hive/REST/Glue) instead of the storage catalog.","If the hint file was deleted, recreate it containing the highest existing `v<N>.metadata.json` version number.","Check object-store lifecycle/retention rules and exclude the `metadata/` prefix from expiration."],"exampleFix":"// before: storage catalog pointed at an external-catalog-managed table\n// after: use the proper catalog config\ncatalog.type = \"rest\" // or \"hive\", matching how the table was created","handlingStrategy":"validation","validationCode":"let hint_path = format!(\"{table_path}/metadata/version-hint.text\");\nif !file_io.exists(&hint_path).await? {\n    return Err(format!(\"{hint_path} missing; use the catalog that manages this table or recreate the hint\"));\n}","typeGuard":null,"tryCatchPattern":"// catch and route to the right catalog\nmatch catalog.commit_table(path, metadata).await {\n    Err(e) if e.to_string().contains(\"no version hint found\") => {\n        return Err(anyhow!(\"table is not managed by the storage catalog; use Hive/REST/Glue\"));\n    }\n    other => other,\n}","preventionTips":["Match catalog type to how the table was created before using storage catalog operations","Double-check table path/identifier spelling before committing","Audit bucket lifecycle rules so metadata files are never expired"],"tags":["iceberg","catalog","file-not-found","storage"],"backgroundTag":"file-not-found","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"}