apache/hadoop · error · NoSuchElementException

No more entries

Error message

No more entries

What it means

PartialListingIterator.next() checks hasNext() first and throws NoSuchElementException('No more entries') when the batched listing is exhausted. This is the standard RemoteIterator contract violation path: the caller asked for an element after the iterator finished. Unlike the IOExceptions around it, this is an unchecked RuntimeException signalling caller misuse.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java:1529

      // If we're done with the current batch, try to get the next batch
      if (listingIdx >= batchedListing.getListings().length) {
        if (!batchedListing.hasMore()) {
          LBI_LOG.trace("No more elements");
          return false;
        }
        batchedListing = dfs.batchedListPaths(
            srcs, batchedListing.getStartAfter(), needLocation);
        LBI_LOG.trace("Got batchedListing: {}", batchedListing);
        listingIdx = 0;
      }
      return listingIdx < batchedListing.getListings().length;
    }

    @Override
    @SuppressWarnings("unchecked")
    public PartialListing<T> next() throws IOException {
      if (!hasNext()) {
        throw new NoSuchElementException("No more entries");
      }
      HdfsPartialListing listing = batchedListing.getListings()[listingIdx];
      listingIdx++;

      Path parent = paths.get(listing.getParentIdx());

      if (listing.getException() != null) {
        return new PartialListing<>(parent, listing.getException());
      }

      // Qualify paths for the client.
      List<HdfsFileStatus> statuses = listing.getPartialListing();
      List<T> qualifiedStatuses =
          Lists.newArrayListWithCapacity(statuses.size());

      for (HdfsFileStatus status : statuses) {
        if (needLocation) {
          qualifiedStatuses.add((T)((HdfsLocatedFileStatus) status)

View on GitHub (pinned to 2add963021)

Solutions

  1. Guard every next() with if (!it.hasNext()) break; before consuming.
  2. Rewrite do/while loops as while (it.hasNext()) loops.
  3. For empty input lists, skip iterator creation entirely.
  4. If bridging to java.util streams, wrap RemoteIterator in a proper guava Iterator adapter that peeks hasNext().

Example fix

// before
do {
  PartialListing<FileStatus> pl = it.next();
  process(pl);
} while (true); // eventually throws NoSuchElementException

// after
while (it.hasNext()) {
  PartialListing<FileStatus> pl = it.next();
  process(pl);
}
Defensive patterns

Strategy: validation

Validate before calling

if (paths.stream().allMatch(p -> false)) { /* empty input */ }
// real guard is the loop shape:
while (it.hasNext()) { PartialListing<FileStatus> pl = it.next(); }

Try / catch

try {
  PartialListing<FileStatus> pl = it.next();
} catch (NoSuchElementException e) {
  // iterator exhausted: should not happen if hasNext() is honored
}

Prevention

When it happens

Trigger: Calling next() without a preceding true result from hasNext(), or calling next() a final time after a hasNext() that returned false; also loops like do/while that assume at least one element exists on an empty batch.

Common situations: while(it.next())-style loops written against Iterator (java.util) semantics; reusing an iterator after a break; adapting code from java.util.Iterator where hasNext/next have the same contract but developers forget RemoteIterator.next() throws IOException; empty directory lists passed to the batched API.

Related errors


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