apache/hadoop · error · IOException

Unable to update the boundaries/Range of contentChannel %s

Error message

Unable to update the boundaries/Range of contentChannel %s

What it means

getStorageReadChannel wraps any exception thrown while configuring the underlying ReadChannel from storage.reader(blobId, options) — seek(seek), limit(limit), setChunkSize(0) — into IOException "Unable to update the boundaries/Range of contentChannel <resourceId>". This happens each time the channel (re)opens a range: initial open, fadvise-driven reopens, seeks beyond inplaceSeekLimit, and footer reads. The specific cause (StorageException, IllegalArgumentException for an invalid range, etc.) is attached.

Source

Thrown at hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorageClientReadChannel.java:537

        skipInPlace();
      } else {
        // close existing contentChannel as requested bytes can't be served from current
        // contentChannel;
        closeContentChannel();
      }
    }

    private ReadableByteChannel getStorageReadChannel(long seek, long limit) throws IOException {
      ReadChannel readChannel = storage.reader(blobId, generateReadOptions());
      try {
        readChannel.seek(seek);
        readChannel.limit(limit);
        // bypass the storage-client caching layer hence eliminates the need to maintain a copy of
        // chunk
        readChannel.setChunkSize(0);
        return readChannel;
      } catch (Exception e) {
        throw new IOException(
            String.format(
                "Unable to update the boundaries/Range of contentChannel %s",
                resourceId.toString()),
            e);
      }
    }

    private BlobSourceOption[] generateReadOptions() {
      List<BlobSourceOption> blobReadOptions = new ArrayList<>();
      // To get decoded content
      blobReadOptions.add(BlobSourceOption.shouldReturnRawInputStream(false));

      if (blobId.getGeneration() != null) {
        blobReadOptions.add(BlobSourceOption.generationMatch(blobId.getGeneration()));
      }

      // TODO: Add support for encryptionKey
      return blobReadOptions.toArray(new BlobSourceOption[blobReadOptions.size()]);

View on GitHub (pinned to 2add963021)

Solutions

  1. Read the cause: for invalid ranges, validate and fix offsets (0 <= seek < limit <= size) in caller math.
  2. Retry once on transient StorageException causes — reader creation can fail transiently.
  3. Align the connector version with the bundled google-cloud-storage client version (no client-side overrides).
  4. Switch range-offset computation from int to long to avoid overflow on multi-GB objects.

Example fix

// before
long rangeEnd = (int) offset + chunkLen; // int overflow for large offsets -> invalid range

// after
long rangeEnd = offset + (long) chunkLen;
rangeEnd = Math.min(rangeEnd, objectSize);
Defensive patterns

Strategy: retry

Validate before calling

// Validate range before any seek-driven read
checkArgument(offset >= 0, "offset must be >= 0");
checkArgument(limit > offset && limit <= objectSize, "need 0 <= offset < limit <= size");
ch.position(offset);

Try / catch

catch (IOException e) {
  boolean invalidRange = e.getCause() instanceof IllegalArgumentException;
  if (!invalidRange && attempt < MAX) { backoff(); retryOpen(); return; } // transient
  throw e; // invalid range = caller bug: fix offset math
}

Prevention

When it happens

Trigger: Any range read that must open or reopen the underlying reader, where seek/limit throws: limit <= seek or negative offsets from caller arithmetic bugs (e.g. int overflow when computing ranges), a storage-client error creating the reader, or transient failures on reader creation.

Common situations: Offset math that overflows or goes negative near large objects (>2GB with int math); connector and google-cloud-storage client version skew breaking reader APIs; transient 5xx when opening a new range; seeks near objectSize against stale metadata.

Related errors


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