OpenFeign/feign · error · IllegalStateException

No More Elements

Error message

No More Elements

What it means

The TokenIterator's next() throws IllegalStateException("No More Elements") when called after the token list is exhausted. Callers must check hasNext() before calling next(), per the Iterator contract this class mimics.

Solutions

  1. Guard every next() call with hasNext()
  2. Verify loop bounds when iterating template tokens manually
  3. Use the public Template API (expand) instead of iterating internal token iterators

Example fix

// before
String token = iterator.next();
// after
String token = iterator.hasNext() ? iterator.next() : null;
Defensive patterns

Strategy: type-guard

Validate before calling

if (iterator.hasNext()) { token = iterator.next(); }

Type guard

String safeNext(Iterator<String> it) { return it.hasNext() ? it.next() : null; }

Try / catch

try {
  token = iterator.next();
} catch (IllegalStateException e) {
  // iterator exhausted; handle end of tokens
}

Prevention

When it happens

Trigger: Calling next() on the internal template token iterator more times than there are tokens, i.e. without a guarding hasNext() check.

Common situations: Custom code iterating Template internals; bugs in chunk()/iteration logic that miscount tokens.

Related errors


AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10). Data as JSON: /api/errors/779e5d223bb6111a. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/feign/template/Template.java:328

            outside = true;
          }
        }
      }
      if (lastIndex < idx) {
        /* grab the remaining chunk */
        tokens.add(template.substring(lastIndex, idx));
      }
    }

    public boolean hasNext() {
      return this.tokens.size() > this.index;
    }

    public String next() {
      if (hasNext()) {
        return this.tokens.get(this.index++);
      }
      throw new IllegalStateException("No More Elements");
    }
  }

  public enum EncodingOptions {
    REQUIRED(true),
    NOT_REQUIRED(false);

    private final boolean shouldEncode;

    EncodingOptions(boolean shouldEncode) {
      this.shouldEncode = shouldEncode;
    }

    public boolean isEncodingRequired() {
      return this.shouldEncode;
    }
  }

View on GitHub (pinned to e2a1e27560)