pinpoint-apm/pinpoint · error · java.util.NoSuchElementException

NoSuchElementException

Error message

NoSuchElementException

What it means

The internal HashIterator's nextEntry() throws NoSuchElementException when nextEntry is null — i.e. next() was called after the iterator was exhausted (or all remaining keys were GC'd). Iterators of this weak map are fail-fast per-call, not per-next: you must check hasNext().

Source

Thrown at commons-profiler/src/main/java/com/navercorp/pinpoint/common/profiler/concurrent/jsr166/ConcurrentWeakHashMap.java:1197

                    }
                }
            }
        }

        public boolean hasNext() {
            while (nextEntry != null) {
                if (nextEntry.keyRef.get() != null)
                    return true;
                advance();
            }

            return false;
        }

        HashEntry<K,V> nextEntry() {
            do {
                if (nextEntry == null)
                    throw new NoSuchElementException();

                lastReturned = nextEntry;
                currentKey = lastReturned.keyRef.get();
                advance();
            } while (currentKey == null); // Skip GC'd keys

            return lastReturned;
        }

        public void remove() {
            if (lastReturned == null)
                throw new IllegalStateException();
            ConcurrentWeakHashMap.this.remove(currentKey);
            lastReturned = null;
        }
    }

    final class KeyIterator

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Always gate next() with hasNext() (or use the for-each/entrySet loop)
  2. Handle the empty-map case before calling next() directly
  3. Since keys can be GC'd, treat a short iteration as normal and re-check size() rather than caching iteration results

Example fix

// before
Iterator<K> it = map.keySet().iterator();
K k = it.next(); // throws when empty
// after
Iterator<K> it = map.keySet().iterator();
if (it.hasNext()) { K k = it.next(); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!map.isEmpty() && it.hasNext()) { K k = it.next(); }

Try / catch

try { K k = it.next(); } catch (NoSuchElementException e) { /* iterator exhausted (or keys GC'd): stop */ }

Prevention

When it happens

Trigger: Calling iterator.next() (or a for-each that manually drives next()) after hasNext() returned false; iterating while GC collects the weakly-referenced keys, exhausting the iterator sooner than expected.

Common situations: Looping map.keySet().iterator().next() assuming at least one element; caching an iterator across awaits/interruptions; weak entries collected between hasNext() and next().

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/a0947a9c6c278095. Report an issue: GitHub.