apache/flink · error · IOException

Premeture EOF from inputStream

Error message

Premeture EOF from inputStream

What it means

IOUtils.skipFully loops in.skip(len) until the requested count is skipped, throwing IOException("Premeture EOF from inputStream") — typo of 'Premature' — when skip returns a negative value. Note the JDK contract says InputStream.skip never returns negative (it returns 0 at EOF), so in practice a conforming stream at EOF causes an infinite loop here; the throw fires only with non-conforming custom streams that return negative on EOF.

Source

Thrown at flink-core/src/main/java/org/apache/flink/util/IOUtils.java:165

            }
            totalRead += read;
        }
        return totalRead;
    }

    /**
     * Similar to readFully(). Skips bytes in a loop.
     *
     * @param in The InputStream to skip bytes from
     * @param len number of bytes to skip
     * @throws IOException if it could not skip requested number of bytes for any reason (including
     *     EOF)
     */
    public static void skipFully(final InputStream in, long len) throws IOException {
        while (len > 0) {
            final long ret = in.skip(len);
            if (ret < 0) {
                throw new IOException("Premeture EOF from inputStream");
            }
            len -= ret;
        }
    }

    // ------------------------------------------------------------------------
    //  Silent I/O cleanup / closing
    // ------------------------------------------------------------------------

    /**
     * Close the AutoCloseable objects and <b>ignore</b> any {@link Exception} or null pointers.
     * Must only be used for cleanup in exception handlers.
     *
     * @param log the log to record problems to at debug level. Can be <code>null</code>.
     * @param closeables the objects to close
     */
    public static void cleanup(final Logger log, final AutoCloseable... closeables) {
        for (AutoCloseable c : closeables) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Fix the custom stream's skip(): at EOF return 0 (per InputStream contract) or throw EOFException, never a negative value
  2. Check available()/read() for EOF before skipping, or verify the byte count you plan to skip matches what was written
  3. If the underlying data is truncated, re-fetch it — the skip demand exceeding remaining bytes indicates corruption upstream

Example fix

// before (custom stream)
@Override public long skip(long n) throws IOException {
    if (atEof) return -1; // triggers 'Premeture EOF'
    ...
}
// after
@Override public long skip(long n) throws IOException {
    if (atEof) return 0;
    ...
}
Defensive patterns

Strategy: validation

Validate before calling

// contract check for custom streams: skip() must never return negative
if (n <= 0 || streamAtEof) return 0; // inside your skip() override

Try / catch

try { IOUtils.skipFully(in, n); } catch (IOException e) { /* EOF signaled by negative skip: treat as truncation */ }

Prevention

When it happens

Trigger: Calling IOUtils.skipFully on a custom InputStream whose skip() implementation returns -1 at end of stream (some hand-rolled or wrapped streams do this), or on a stream already at/past EOF with such an implementation.

Common situations: Wrapping Flink's FSDataInputStream or user streams in adapters where skip is overridden with `return -1;` at EOF; deserialization code skipping over padding in truncated input.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/fa7856928b1997a1. Report an issue: GitHub.