apache/iceberg · error · RuntimeIOException

Failed calling close

Error message

Failed calling close

What it means

Exceptions.close(Closeable, boolean) wraps any IOException thrown while closing a resource into a RuntimeIOException with message 'Failed calling close', unless suppression is requested. It surfaces close-time failures instead of silently swallowing them.

Source

Thrown at core/src/main/java/org/apache/iceberg/util/Exceptions.java:33

 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.iceberg.util;

import java.io.Closeable;
import java.io.IOException;
import org.apache.iceberg.exceptions.RuntimeIOException;

public class Exceptions {
  private Exceptions() {}

  public static void close(Closeable closeable, boolean suppressExceptions) {
    try {
      closeable.close();
    } catch (IOException e) {
      if (!suppressExceptions) {
        throw new RuntimeIOException(e, "Failed calling close");
      }
      // otherwise, ignore the exception
    }
  }

  public static <E extends Exception> E suppressExceptions(E alreadyThrown, Runnable run) {
    try {
      run.run();
    } catch (Exception e) {
      alreadyThrown.addSuppressed(e);
    }
    return alreadyThrown;
  }

  public static <E extends Exception> void suppressAndThrow(E alreadyThrown, Runnable run)
      throws E {
    throw suppressExceptions(alreadyThrown, run);
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check the underlying storage for space/permission/connectivity problems indicated by the wrapped cause
  2. Use suppressExceptions=true for cleanup code that must not mask the primary failure
  3. Close resources with try-with-resources so the close exception is properly suppressed alongside the main exception

Example fix

// before
Exceptions.close(stream, false); // may mask primary failure
// after
try {
  // primary work
} finally {
  Exceptions.close(stream, true);
}
Defensive patterns

Strategy: try-catch

Try / catch

try { Exceptions.close(closeable, false); } catch (RuntimeIOException e) { LOG.warn("close failed", e.getCause()); }

Prevention

When it happens

Trigger: Calling Exceptions.close(closeable, false) where the underlying stream's close() throws IOException — e.g., flushing buffered data to a failed file system or network target during close.

Common situations: Closing a Parquet/Avro writer whose output stream hits a disk-full or permission error; closing Hadoop/LocalInputFile streams in error paths where the original exception gets replaced or masked by this close failure.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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