apache/hadoop · error · NoSuchElementException

No more items in iterator.

Error message

No more items in iterator.

What it means

Iterables wraps and transforms iterators for the hadoop-tos connector; this next() implementation caches the element produced by hasNext() and throws NoSuchElementException('No more items in iterator.') when next() is called after the underlying iteration is exhausted. In other words hasNext() was false (or was never consulted) and the caller still demanded an element — a strict iterator-protocol violation, not a storage problem.

Source

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

        while (iterator.hasNext()) {
          value = iterator.next();
          if (predicate.test(value)) {
            advance = false;
            return true;
          }
        }

        return false;
      }

      @Override
      public T next() {
        if (hasNext()) {
          advance = true;
          return value;
        }
        throw new NoSuchElementException("No more items in iterator.");
      }
    };
  }

  public static <T extends @Nullable Object> Iterable<T> concat(
      Iterable<? extends Iterable<? extends T>> inputs) {
    return () -> new ConcatenatedIterator<>(inputs.iterator());
  }

  private static class ConcatenatedIterator<T> implements Iterator<T> {
    // Iterators is the iterator of iterables.
    private final Iterator<? extends Iterable<? extends T>> iterators;
    private Iterator<? extends T> curIter;

    ConcatenatedIterator(Iterator<? extends Iterable<? extends T>> iterators) {
      Preconditions.checkNotNull(iterators, "Iterators should not be null.");
      this.iterators = iterators;
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Guard every next() with hasNext(): while (it.hasNext()) { T v = it.next(); ... }
  2. For 'expect exactly one element' logic, use hasNext() to branch explicitly instead of calling next() unconditionally.
  3. Search the stack trace for your loop frame — the connector class is fine; the defect is at the caller.
  4. If using Java 8+, prefer stream(Iterable).findFirst()/collect instead of manual iteration to eliminate the pattern.

Example fix

// before
T first = it.next(); // throws on empty iterable

// after
if (!it.hasNext()) { throw new IllegalStateException(...); }
T first = it.next();
Defensive patterns

Strategy: validation

Validate before calling

Iterator<T> it = iterable.iterator();
while (it.hasNext()) {
  T v = it.next();
  process(v);
}

Try / catch

try { first = it.next(); }
catch (NoSuchElementException e) { first = defaultValue; }

Prevention

When it happens

Trigger: Calling it.next() without checking it.hasNext(), or calling next() a second time after a final hasNext()==false in loops over Iterables.transformed/filtered results, e.g. object listing helpers that iterate keys or upload parts.

Common situations: Hand-written for(;;) loops using next() alone; code that assumes at least one element exists (first()/single-item expectations) on an empty listing; off-by-one loop counters over connector-returned Iterables; refactors that removed a hasNext() guard.

Related errors


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