jwtk/jjwt · error · java.lang.UnsupportedOperationException
${getName()} instance is immutable and may not be modified.
Error message
${getName()} instance is immutable and may not be modified. What it means
ParameterMap (used for JWT/Claims/Jws header and claims collections) becomes immutable once finalized/initialized; afterwards any mutating call (put, remove, clear) is rejected with UnsupportedOperationException. The library protects header/claims instances handed to the user so parsed tokens cannot be modified in place.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/ParameterMap.java:80
}
public ParameterMap(Registry<String, ? extends Parameter<?>> registry, Map<String, ?> values, boolean mutable) {
Assert.notNull(registry, "Parameter registry cannot be null.");
Assert.notEmpty(registry.values(), "Parameter registry cannot be empty.");
this.PARAMS = registry;
this.values = new LinkedHashMap<>();
this.idiomaticValues = new LinkedHashMap<>();
if (!Collections.isEmpty(values)) {
putAll(values);
}
this.mutable = mutable;
this.initialized = true;
}
private void assertMutable() {
if (initialized && !mutable) {
String msg = getName() + " instance is immutable and may not be modified.";
throw new UnsupportedOperationException(msg);
}
}
protected ParameterMap replace(Parameter<?> param) {
Registry<String, ? extends Parameter<?>> registry = Parameters.replace(this.PARAMS, param);
return new ParameterMap(registry, this, this.mutable);
}
@Override
public String getName() {
return "Map";
}
@Override
public <T> T get(Parameter<T> param) {
Assert.notNull(param, "Parameter cannot be null.");
final String id = Assert.hasText(param.getId(), "Parameter id cannot be null or empty.");
Object value = idiomaticValues.get(id);View on GitHub (pinned to fb71496164)
Solutions
- Create a new mutable map: new HashMap<>(claims), mutate the copy, and build a new JWT with Jwts.builder().setClaims(copy)
- Use Jwts.builder() to construct modified tokens instead of mutating parsed ones
- If constructing your own ParameterMap, keep it mutable (mutable=true) until you intentionally finalize it
Example fix
// before
Claims claims = Jwts.parser().verifyWith(key).parseClaimsJws(jwt).getBody();
claims.put("role", "admin"); // UnsupportedOperationException
// after
Claims claims = Jwts.parser().verifyWith(key).parseClaimsJws(jwt).getBody();
Map<String, Object> updated = new HashMap<>(claims);
updated.put("role", "admin");
String newJwt = Jwts.builder().setClaims(updated).signWith(key).compact(); Defensive patterns
Strategy: type-guard
Validate before calling
// copy before mutating
Map<String, Object> editable = new HashMap<>(jws.getHeader());
editable.put("typ", "JWT"); Type guard
boolean isMutable(ParameterMap map) {
try { map.isEmpty(); return true; } catch (UnsupportedOperationException e) { return false; }
} Try / catch
try {
claims.put("role", "admin");
} catch (UnsupportedOperationException e) {
claims = Jwts.claims(new HashMap<>(claims)); // rebuild mutable instance
} Prevention
- Treat parsed header/Claims instances as read-only views
- Always copy into a HashMap before modifying claims
- Rebuild tokens with Jwts.builder() rather than mutating parsed ones
When it happens
Trigger: Calling put/remove/clear on a Jws.getHeader(), Claims instance obtained from a parsed token, or any ParameterMap after it has been initialized as immutable (e.g. the claims returned by parseClaimsJws).
Common situations: Trying to add a claim to a parsed token's Claims before re-signing; mutating header maps returned from Jws; building code that assumes mutable Maps because Claims extends Map.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- JWKs are immutable and may not be modified.
- Not intended to be called.
- Unexpected unsecured Claims JWT.
- Unexpected content JWS.
- Unexpected Claims JWS.
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/1bc85f2a102b8182.
Report an issue: GitHub.