apache/hadoop · error · IOException

Seek not supported

Error message

Seek not supported

What it means

FTPInputStream wraps a strictly sequential FTP data connection; seek(long) always throws IOException("Seek not supported") because the implementation never restarts a RETR at an offset (no REST command). The position only advances via reads, and getPos() merely reports it.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/ftp/FTPInputStream.java:62

    if (client == null || !client.isConnected()) {
      throw new IllegalArgumentException("FTP client null or not connected");
    }
    this.wrappedStream = stream;
    this.client = client;
    this.stats = stats;
    this.pos = 0;
    this.closed = false;
  }

  @Override
  public long getPos() throws IOException {
    return pos;
  }

  // We don't support seek.
  @Override
  public void seek(long pos) throws IOException {
    throw new IOException("Seek not supported");
  }

  @Override
  public boolean seekToNewSource(long targetPos) throws IOException {
    throw new IOException("Seek not supported");
  }

  @Override
  public synchronized int read() throws IOException {
    if (closed) {
      throw new IOException("Stream closed");
    }

    int byteRead = wrappedStream.read();
    if (byteRead >= 0) {
      pos++;
    }
    if (stats != null && byteRead >= 0) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Reopen the stream and skip forward to the offset instead of seeking (sequential skip is supported)
  2. Copy the file to HDFS or local disk first (FileUtil.copy/distcp) and run seek-heavy code there
  3. Restructure reading into a single forward pass (streaming parser)
  4. Branch on fs.getUri().getScheme() and only call seek on seek-capable filesystems

Example fix

// before
try (FSDataInputStream in = fs.open(path)) {
  in.seek(offset);            // IOException: Seek not supported
  in.readFully(buf);
}

// after
try (FSDataInputStream in = fs.open(path)) {
  long skipped = 0;
  while (skipped < offset) {
    skipped += in.skip(offset - skipped);   // forward-only positioning
  }
  in.readFully(buf);
}
Defensive patterns

Strategy: fallback

Validate before calling

// avoid seek() on sequential-only filesystems
boolean seekable = !"ftp".equalsIgnoreCase(fs.getUri().getScheme());
if (!seekable && targetPos != in.getPos()) {
  // reposition by reopen + skip instead of seek
}

Try / catch

catch IOException from seek(), verify "Seek not supported", then close and reopen the stream at the required offset using skip(); keep getPos() before failing to make the resume point exact.

Prevention

When it happens

Trigger: Calling FSDataInputStream.seek() on a stream from FTPFileSystem.open(path): split-based readers (MapReduce input formats), calling seek(0) to restart parsing, PositionedReadable/readFully helpers that seek internally, or format readers (Avro/Parquet) fetching footers from the end of the file.

Common situations: Running compute frameworks or splittable formats directly over ftp:// URLs; generic code assuming every FileSystem's streams are seekable; re-reading input by seeking back after a parse failure.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/e4cf24a78c247545. Report an issue: GitHub.