apache/iceberg · error · RuntimeIOException

Failed to get stream length: no open stream

Error message

Failed to get stream length: no open stream

What it means

AvroFileAppender.length() throws RuntimeIOException('Failed to get stream length: no open stream') when called while the appender has no open output stream. This happens before the file is opened or after the appender has been closed and the stream released. Callers must only query length while a stream exists (typically before close).

Source

Thrown at core/src/main/java/org/apache/iceberg/avro/AvroFileAppender.java:88

  }

  @Override
  public Metrics metrics() {
    Preconditions.checkState(isClosed, "Cannot return metrics while appending to an open file.");

    return AvroMetrics.fromWriter(datumWriter, icebergSchema, numRecords, metricsConfig);
  }

  @Override
  public long length() {
    if (stream != null) {
      try {
        return stream.storedLength();
      } catch (IOException e) {
        throw new RuntimeIOException(e, "Failed to get stream length");
      }
    }
    throw new RuntimeIOException("Failed to get stream length: no open stream");
  }

  @Override
  public void close() throws IOException {
    if (writer != null) {
      writer.close();
      this.writer = null;
      isClosed = true;
    }
  }

  @SuppressWarnings("unchecked")
  private static <D> DataFileWriter<D> newAvroWriter(
      Schema schema,
      PositionOutputStream stream,
      DatumWriter<?> metricsAwareDatumWriter,
      CodecFactory codec,
      Map<String, String> metadata)

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Call length() only after the appender has written data (stream is open) and before close()
  2. Capture the file length before closing, or obtain length from the OutputFile after close if the API supports it
  3. Guard the call: check the appender state/lifecycle before querying length
  4. Restructure commit logic so metrics/length are read during the append phase

Example fix

// before
appender.close();
long len = appender.length(); // no open stream

// after
long len = appender.length();
appender.close();
Defensive patterns

Strategy: type-guard

Type guard

boolean canQueryLength = appenderOpen && !appenderClosed; // track lifecycle in wrapper

Try / catch

try { return appender.length(); } catch (RuntimeIOException e) { if (e.getMessage().contains("no open stream")) { /* fix lifecycle: capture length before close */ } throw e; }

Prevention

When it happens

Trigger: Calling length() on a freshly constructed AvroFileAppender before any write opened the stream, or after close() has completed; using an appender from the wrong lifecycle stage during commit.

Common situations: Custom commit logic querying file length after closing the writer; error-handling paths that inspect length on a never-opened appender; double-close scenarios.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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