{"record":{"id":"65197c3fb8ef6718","repo":"risingwavelabs/risingwave","slug":"parse-version-hint-failed","errorCode":null,"errorMessage":"parse version hint failed","messagePattern":"parse version hint failed","errorType":"error_code","errorClass":"iceberg::Error(ErrorKind::DataInvalid)","httpStatus":null,"severity":"error","filePath":"src/connector/src/connector_common/iceberg/storage_catalog.rs","lineNumber":173,"sourceCode":"    async fn read_version_hint(&self, table_path: &str) -> Result<i32> {\n        let content = self\n            .file_io\n            .new_input(format!(\"{table_path}/metadata/version-hint.text\").as_str())?\n            .read()\n            .await?;\n        let version_hint = String::from_utf8(content.to_vec()).map_err(|err| {\n            Error::new(\n                ErrorKind::DataInvalid,\n                format!(\n                    \"Fail to convert version_hint from utf8 to string: {}\",\n                    err.as_report()\n                ),\n            )\n        })?;\n\n        version_hint\n            .parse()\n            .map_err(|_| Error::new(ErrorKind::DataInvalid, \"parse version hint failed\"))\n    }\n\n    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? {","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/connector_common/iceberg/storage_catalog.rs#L155-L191","documentation":"The storage (filesystem-based) Iceberg catalog reads the table's `version-hint.text` file to learn the current metadata file version, then tries to parse it as an integer. This error is thrown when the file exists but its contents cannot be parsed as a number, so the catalog cannot determine which `v<N>.metadata.json` file to load or commit.","triggerScenarios":"Calling commit_table or load_table (via update_table/drop_table) when `{table_path}/metadata/version-hint.text` exists but contains non-numeric content: empty file, whitespace/newline-only, BOM characters, or text accidentally written instead of a version integer.","commonSituations":"A version-hint file truncated by a failed concurrent write, manually edited by an operator, corrupted by a sync tool, or written by a different tool in an incompatible format (e.g. with trailing garbage or a UTF-8 BOM).","solutions":["Inspect the contents of `{table_path}/metadata/version-hint.text` and rewrite it as a plain integer equal to the latest metadata version (e.g. `5` for `v5.metadata.json`).","Check the listed `v*.metadata.json` files and set the hint to the highest version number found.","Remove concurrent writers or ensure atomic writes of the version-hint file to prevent truncated content.","If the file is irrecoverable and no writers depend on it, recreate the catalog/table registration against a catalog implementation that does not rely on version hints."],"exampleFix":"// before: file contains \"05\\n \\u{feef}\" or garbage\n// after: rewrite the hint file with the exact integer\necho -n \"3\" > s3://bucket/db/table/metadata/version-hint.text","handlingStrategy":"validation","validationCode":"let hint = file_io.read(format!(\"{table_path}/metadata/version-hint.text\")).await?;\nlet s = String::from_utf8_lossy(&hint).trim().to_string();\nif s.is_empty() || s.parse::<i64>().is_err() {\n    return Err(\"version-hint.text is not a valid integer; repair before committing\");\n}","typeGuard":"fn is_valid_version_hint(raw: &str) -> bool {\n    raw.trim().parse::<i64>().is_ok()\n}","tryCatchPattern":null,"preventionTips":["Never hand-edit version-hint.text; always write a plain integer with atomic rename","Exclude the Iceberg metadata/ prefix from object-store lifecycle and sync tools","Validate hint parseability as part of table health checks"],"tags":["iceberg","catalog","file-parsing","storage"],"backgroundTag":"invalid-argument-format","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"}