apache/hadoop · error · NoSuchElementException

No more elements

Error message

No more elements

What it means

The ConcatenatedIterator inside Iterables#concat chains multiple sub-iterables; its next() throws NoSuchElementException('No more elements') when hasNext() is false — every sub-iterator is exhausted (or all were empty). Same protocol rule as [286]: the exception signals caller misuse, specifically consuming a concatenated iterable past its end.

Source

Thrown at hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/util/Iterables.java:125

        if (curIter != null) {
          curIter = null;
        }

        if (!iterators.hasNext()) {
          return false;
        }

        curIter = iterators.next().iterator();
      }
      return true;
    }

    @Override
    public T next() {
      if (hasNext()) {
        return curIter.next();
      }
      throw new NoSuchElementException("No more elements");
    }
  }
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Always gate next() with hasNext() — including when you 'know' the collection is non-empty.
  2. Handle the empty-aggregate case explicitly before iterating (size check, isEmpty branch, or Optional-style wrapping).
  3. Replace peek-by-next() with a hasNext()-based peek or a defensive copy you then inspect.
  4. Unit-test the empty-input path of whatever builds the concatenated iterable.

Example fix

// before
Iterator<T> it = Iterables.concat(lists).iterator();
T only = it.next(); // NoSuchElementException when all lists empty

// after
Iterable<T> all = Iterables.concat(lists);
if (all.iterator().hasNext()) { T only = all.iterator().next(); } else { /* empty path */ }
Defensive patterns

Strategy: validation

Validate before calling

Iterable<T> all = Iterables.concat(lists);
Iterator<T> it = all.iterator();
if (it.hasNext()) { T first = it.next(); } else { /* explicit empty branch */ }

Try / catch

try { T v = it.next(); }
catch (NoSuchElementException e) { /* exhausted: finish loop cleanly */ }

Prevention

When it happens

Trigger: Iterating the result of Iterables.concat(...) and calling next() after the final element, or assuming a non-empty chain (e.g. concat of N part-lists where every part-list came back empty) and unconditionally taking the first element.

Common situations: Multipart-upload part enumeration where all parts lists are empty; merging paginated object listings and forgetting the aggregate can be empty; utility code that does iterator.next() to peek instead of hasNext().

Related errors


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