{"record":{"id":"e276037f07516e01","repo":"apache/iceberg","slug":"failed-to-write-json-to-file-s","errorCode":null,"errorMessage":"Failed to write json to file: %s","messagePattern":"Failed to write json to file: (.+?)","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/TableMetadataParser.java","lineNumber":136,"sourceCode":"  public static void overwrite(TableMetadata metadata, OutputFile outputFile) {\n    internalWrite(metadata, outputFile, true);\n  }\n\n  public static void write(TableMetadata metadata, OutputFile outputFile) {\n    internalWrite(metadata, outputFile, false);\n  }\n\n  public static void internalWrite(\n      TableMetadata metadata, OutputFile outputFile, boolean overwrite) {\n    boolean isGzip = Codec.fromFileName(outputFile.location()) == Codec.GZIP;\n    OutputStream stream = overwrite ? outputFile.createOrOverwrite() : outputFile.create();\n    try (OutputStream ou = isGzip ? new GZIPOutputStream(stream) : stream;\n        OutputStreamWriter writer = new OutputStreamWriter(ou, StandardCharsets.UTF_8);\n        JsonGenerator generator = JsonUtil.factory().createGenerator(writer)) {\n      toJson(metadata, generator);\n      generator.flush();\n    } catch (IOException e) {\n      throw new RuntimeIOException(e, \"Failed to write json to file: %s\", outputFile.location());\n    }\n  }\n\n  public static String getFileExtension(String codecName) {\n    return getFileExtension(Codec.fromName(codecName));\n  }\n\n  public static String getFileExtension(Codec codec) {\n    return codec.extension + \".metadata.json\";\n  }\n\n  public static String getOldFileExtension(Codec codec) {\n    // we have to be backward-compatible with .metadata.json.gz files\n    return \".metadata.json\" + codec.extension;\n  }\n\n  public static String toJson(TableMetadata metadata) {\n    try (StringWriter writer = new StringWriter();","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/TableMetadataParser.java#L118-L154","documentation":"internalWrite serializes TableMetadata to JSON and streams it (optionally gzip-compressed) to an output file. Any IOException from the underlying FileIO stream is wrapped in RuntimeIOException with the output file location. This indicates the metadata JSON could not be written to storage — an I/O or filesystem-level failure, not a serialization bug.","triggerScenarios":"Any table commit (write/overwrite) that creates a new metadata JSON via TableMetadataParser.overwrite or write when the underlying OutputStream raises IOException: storage outage, quota exceeded, permission denied on the metadata directory, network failure to object store.","commonSituations":"S3/GCS/HDFS transient outages or throttling during commits; wrong credentials or missing write permission on the table location; disk full on local/HDFS paths; anti-virus or permission churn on local filesystems.","solutions":["Inspect the chained cause (getCause) for the real storage error and fix that condition","Retry the commit — Iceberg commits are safe to retry; a transient object-store blip is the most common cause","Verify write credentials/permissions on the table's metadata location","Check storage quota/disk space and network connectivity to the object store"],"exampleFix":"// before\nTableMetadataParser.overwrite(metadata, outputFile); // throws on transient S3 503\n// after\nTasks.foreach(metadata)\n    .retry(3)\n    .exponentialBackoff(100, 1000, 10000)\n    .throwFailureWhenFinished()\n    .run(m -> TableMetadataParser.overwrite(m, outputFile));","handlingStrategy":"retry","validationCode":"// pre-check storage writability\ntry (OutputStream out = fileIO.newOutputFile(tmpLoc).createOrOverwrite()) { out.write(1); }","typeGuard":null,"tryCatchPattern":"try { TableMetadataParser.overwrite(metadata, outputFile); }\ncatch (RuntimeIOException e) {\n  LOG.error(\"Metadata write failed for {}: cause={}\", outputFile.location(), e.getCause(), e);\n  throw e;\n}","preventionTips":["Retry commits with Tasks.foreach retry + exponential backoff for transient object-store errors","Monitor storage quota, disk space, and bucket permissions","Verify FileIO credentials before long-running write jobs","Inspect e.getCause() to distinguish permission vs connectivity vs quota failures"],"tags":["io","file-write","runtime-io-exception","iceberg"],"backgroundTag":"file-write-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}