risingwavelabs/risingwave · error · iceberg::Error(ErrorKind::DataInvalid)

Fail to convert version_hint from utf8 to string: {}

Error message

Fail to convert version_hint from utf8 to string: {}

What it means

When no metadata/version-hint.text check succeeds, the catalog reads that file's bytes and converts them to a UTF-8 string to get the current version number. If the bytes are not valid UTF-8, the read fails wrapped as DataInvalid with this message.

Source

Thrown at src/connector/src/connector_common/iceberg/storage_catalog.rs:162

            .map_err(|err| {
                Error::new(
                    ErrorKind::DataInvalid,
                    format!("check if version hint exist failed: {}", err.as_report()),
                )
            })
    }

    /// Read version hint of table.
    ///
    /// `table_path`: relative path of table dir under warehouse root.
    async fn read_version_hint(&self, table_path: &str) -> Result<i32> {
        let content = self
            .file_io
            .new_input(format!("{table_path}/metadata/version-hint.text").as_str())?
            .read()
            .await?;
        let version_hint = String::from_utf8(content.to_vec()).map_err(|err| {
            Error::new(
                ErrorKind::DataInvalid,
                format!(
                    "Fail to convert version_hint from utf8 to string: {}",
                    err.as_report()
                ),
            )
        })?;

        version_hint
            .parse()
            .map_err(|_| Error::new(ErrorKind::DataInvalid, "parse version hint failed"))
    }

    pub fn file_io(&self) -> &FileIO {
        &self.file_io
    }

    fn table_path(&self, table: &TableIdent) -> String {

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Inspect version-hint.text in the table's metadata/ directory and rewrite it as plain ASCII/UTF-8 containing only the version number.
  2. Restore the file from a known-good backup or let the writer engine (e.g. Spark/Flink) rewrite the table metadata.
  3. Check what process wrote the file — disable compression or non-UTF-8 encodings in that tool.
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check: fetch version-hint.text and confirm it decodes as UTF-8 text
// curl -s <storage>/db/table/metadata/version-hint.text | file -  => should be 'ASCII text'

Try / catch

// Rust caller pattern
match catalog.load_table("db.table").await {
    Err(e) if e.to_string().contains("Fail to convert version_hint from utf8") => {
        // repair/rewrite version-hint.text as UTF-8, then retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: read_version_hint loads <table_path>/metadata/version-hint.text via file_io and String::from_utf8 fails because the object contains binary data, an unexpected compression, or a corrupt/truncated write — reached from commit_table or load_table.

Common situations: Corrupted upload to the object store (partial/mangled version-hint.text); another tool writing the hint as UTF-16 or gzip; manual edits to metadata files.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/cb1cdf17c58f8f58. Report an issue: GitHub.