spring-projects/spring-security · error · IllegalStateException

invalid item: " + item.getClass()

Error message

invalid item: " + item.getClass()

What it means

ComparableVersion's BigIntegerItem.compareTo throws IllegalStateException('invalid item: ' + item.getClass()) when a BigInteger version item meets a type not covered by its switch branch (only INT, LONG, BIGINTEGER, STRING, LIST are handled). Hitting default indicates the comparison matrix between parsed item types was violated — an internal invariant of ComparableVersion.

Source

Thrown at core/src/main/java/org/springframework/security/core/ComparableVersion.java:269

		}

		@Override
		public boolean isNull() {
			return BigInteger.ZERO.equals(value);
		}

		@Override
		public int compareTo(@Nullable Item item) {
			if (item == null) {
				return BigInteger.ZERO.equals(value) ? 0 : 1; // 1.0 == 1, 1.1 > 1
			}

			return switch (item.getType()) {
				case INT_ITEM, LONG_ITEM -> 1;
				case BIGINTEGER_ITEM -> value.compareTo(((BigIntegerItem) item).value);
				case STRING_ITEM -> 1; // 1.1 > 1-sp
				case LIST_ITEM -> 1; // 1.1 > 1-1
				default -> throw new IllegalStateException("invalid item: " + item.getClass());
			};
		}

		@Override
		public boolean equals(@Nullable Object o) {
			if (this == o) {
				return true;
			}
			if (o == null || getClass() != o.getClass()) {
				return false;
			}

			BigIntegerItem that = (BigIntegerItem) o;

			return value.equals(that.value);

		}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Remove duplicate/shaded copies of ComparableVersion from the classpath so a single consistent implementation parses and compares items
  2. Keep numeric version segments within long range to avoid BigInteger items entirely
  3. Upgrade to the fixed Spring Security release where cross-type comparisons are complete
  4. Catch IllegalStateException around comparisons of untrusted version strings and fall back to lexicographic comparison

Example fix

// before
new ComparableVersion("999999999999999999999999999999").compareTo(other) // BigIntegerItem path
// after
new ComparableVersion("1.0.0").compareTo(other) // bounded numeric segments
Defensive patterns

Strategy: fallback

Validate before calling

if (version.matches(".*\\d{30,}.*")) { throw new IllegalArgumentException("numeric version segment too large: " + version); }

Try / catch

int cmp; try { cmp = new ComparableVersion(a).compareTo(new ComparableVersion(b)); } catch (IllegalStateException e) { cmp = a.compareTo(b); }

Prevention

When it happens

Trigger: Comparing versions whose numeric segments overflow to BigInteger against exotic qualifier items produced by a different parser or patched copy; programmatic construction of item lists bypassing ComparableVersion's own parser.

Common situations: Maven-style version strings with astronomically large numeric parts; classpath containing multiple divergent copies of ComparableVersion (shaded jars) so items from one copy are compared by another with a different switch.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/0449bee1f42ae598. Report an issue: GitHub.