{"record":{"id":"7e46fbf156b67b5e","repo":"apache/iceberg","slug":"failed-to-refresh-the-table","errorCode":null,"errorMessage":"Failed to refresh the table","messagePattern":"Failed to refresh the table","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/hadoop/HadoopTableOperations.java","lineNumber":126,"sourceCode":"        return null;\n      } else if (metadataFile == null) {\n        throw new ValidationException(\n            \"Metadata file for version %d is missing under %s\", ver, metadataRoot());\n      }\n\n      Path nextMetadataFile = getMetadataFile(ver + 1);\n      while (nextMetadataFile != null) {\n        ver += 1;\n        metadataFile = nextMetadataFile;\n        nextMetadataFile = getMetadataFile(ver + 1);\n      }\n\n      updateVersionAndMetadata(ver, metadataFile.toString());\n\n      this.shouldRefresh = false;\n      return currentMetadata;\n    } catch (IOException e) {\n      throw new RuntimeIOException(e, \"Failed to refresh the table\");\n    }\n  }\n\n  @Override\n  public void commit(TableMetadata base, TableMetadata metadata) {\n    Pair<Integer, TableMetadata> current = versionAndMetadata();\n    if (base != current.second()) {\n      throw new CommitFailedException(\"Cannot commit changes based on stale table metadata\");\n    }\n\n    if (base == metadata) {\n      LOG.info(\"Nothing to commit.\");\n      return;\n    }\n\n    Preconditions.checkArgument(\n        base == null || base.location().equals(metadata.location()),\n        \"Hadoop path-based tables cannot be relocated\");","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/hadoop/HadoopTableOperations.java#L108-L144","documentation":"refresh() wraps IO errors encountered while reading version hint or metadata files into RuntimeIOException with this message. The underlying IOException (access problem, FS outage) is the cause. It signals the refresh could not read table metadata from the filesystem.","triggerScenarios":"IOException while reading version-hint.text or the version metadata file during refresh(): HDFS NameNode unavailable, permission denied on metadata files, network partition to HDFS/S3, corrupted file causing read failure.","commonSituations":"HDFS cluster restarted or in safe mode; Kerberos credentials expired; S3 endpoint misconfigured; transient network failure in a long-running Spark job reading a table.","solutions":["Check the cause chain for the underlying IOException and fix FS connectivity/permissions","Retry after confirming the filesystem is reachable (hdfs dfs -ls on the metadata path)","Refresh Kerberos tokens / credentials if auth expired","Validate the storage endpoint configuration (fs.defaultFS, S3 endpoint) is correct"],"exampleFix":"// before: table ref held across a long job, refresh hits HDFS outage\nTable table = catalog.loadTable(...); // used hours later\n// after: reload/retry around refresh\ntry {\n  table.refresh();\n} catch (RuntimeIOException e) {\n  table = catalog.loadTable(identifier); // reconnect and retry\n}","handlingStrategy":"retry","validationCode":"if (!fs.exists(new Path(root, \"metadata/version-hint.text\"))) throw new SkipRefreshException();","typeGuard":null,"tryCatchPattern":"try { table.refresh(); } catch (RuntimeIOException e) { LOG.warn(\"refresh failed\", e.getCause()); /* reconnect / retry with backoff */ }","preventionTips":["Keep HDFS/storage connectivity healthy before long jobs","Refresh Kerberos tokens for long-running applications","Retry refresh with exponential backoff on transient IO errors","Reload the table from the catalog as fallback after repeated failures"],"tags":["io","hadoop","filesystem"],"backgroundTag":"file-read-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}