apache/iceberg · warning

Error reading version hint file

Error message

Error reading version hint file {}

What it means

HadoopTableOperations.findVersion() reads the version-hint.text file to determine the current metadata version. When parsing fails (unreadable, corrupted, or missing content), it logs this warning and attempts recovery by listing the metadata directory for version files and returning the max. It is a warning, not a thrown exception; the table version is recovered or 0 is returned.

Solutions

  1. Check that version-hint.text exists and contains a single integer line at the table metadata root
  2. Restore the file from a healthy replica of the table location
  3. Recreate or repair the version hint by writing the current max metadata version number to version-hint.text
  4. Verify filesystem connectivity/permissions so the read does not fail
  5. Upgrade Iceberg; newer versions improve version-hint recovery robustness

Example fix

// before (corrupted version-hint.text)
cat /table/metadata/version-hint.text  # -> empty or garbage
// after
echo 12 > /table/metadata/version-hint.text  # matches v12.metadata.json
Defensive patterns

Strategy: fallback

Validate before calling

Path vh = new Path(metadataRoot, "version-hint.text");
if (!fs.exists(vh)) { /* repair before opening table */ }
try (FSDataInputStream in = fs.open(vh)) {
  Integer.parseInt(in.readLine().trim()); // must parse as int
}

Try / catch

try {
  int v = ops.currentVersion();
} catch (RuntimeException e) {
  // recovery already logs; reload table or repair version-hint.text
}

Prevention

When it happens

Trigger: Calling HadoopTableOperations.ver()/findVersion() when version-hint.text cannot be read: the file exists but is empty, contains non-numeric text, was partially written, or the underlying FileSystem read throws an IOException while metadataRoot() still exists.

Common situations: Manually copied or synced table locations (e.g. S3/HDFS distcp) where version-hint.text was missed or truncated; concurrent writer racing a reader during table creation; HDFS read errors or NameNode failover mid-read.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/bd06772262de6add. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/hadoop/HadoopTableOperations.java:325

    try (FSDataOutputStream out = fs.create(path, false /* overwrite */)) {
      out.write(String.valueOf(versionToWrite).getBytes(StandardCharsets.UTF_8));
    }
  }

  @VisibleForTesting
  int findVersion() {
    Path versionHintFile = versionHintFile();
    FileSystem fs = getFileSystem(versionHintFile, conf);

    try (InputStreamReader fsr =
            new InputStreamReader(fs.open(versionHintFile), StandardCharsets.UTF_8);
        BufferedReader in = new BufferedReader(fsr)) {
      return Integer.parseInt(in.readLine().replace("\n", ""));

    } catch (Exception e) {
      try {
        if (fs.exists(metadataRoot())) {
          LOG.warn("Error reading version hint file {}", versionHintFile, e);
        } else {
          LOG.debug("Metadata for table not found in directory {}", metadataRoot(), e);
          return 0;
        }

        // List the metadata directory to find the version files, and try to recover the max
        // available version
        FileStatus[] files =
            fs.listStatus(
                metadataRoot(), name -> VERSION_PATTERN.matcher(name.getName()).matches());
        int maxVersion = 0;

        for (FileStatus file : files) {
          int currentVersion = version(file.getPath().getName());
          if (currentVersion > maxVersion && getMetadataFile(currentVersion) != null) {
            maxVersion = currentVersion;
          }
        }

View on GitHub (pinned to 86d9c8fc54)