jwtk/jjwt · error · UnsupportedOperationException

JWKs are immutable and may not be modified.

Error message

JWKs are immutable and may not be modified.

What it means

JWK instances expose a read-only Map view over their name/value pairs. Any mutation attempt (put, remove, putAll, clear) throws UnsupportedOperationException because RFC 7517 JWKs are treated as immutable once built.

Solutions

  1. Set all desired fields on the JwkContext before building: Jwks.builder().put(...).build().
  2. Create a new JWK with the additional values instead of mutating the existing one.
  3. If you need a mutable copy: new HashMap<>(jwk) and mutate that.
  4. Never write through the entrySet() view; it is wrapped by Collections.immutable.

Example fix

// before
jwk.put("kid", "my-key-id");
// after
Jwk<?> updated = Jwks.builder().putAll(jwk).put("kid", "my-key-id").build();
Defensive patterns

Strategy: type-guard

Type guard

boolean isMutable(Map<String,Object> m) { try { m.size(); return !(m instanceof Jwk); } catch (UnsupportedOperationException e) { return false; } }

Try / catch

try { map.put(k, v); }
catch (UnsupportedOperationException e) { throw new IllegalStateException("JWKs are immutable; rebuild instead", e); }

Prevention

When it happens

Trigger: Calling jwk.put("kid", v), jwk.remove(...), jwk.putAll(...), or jwk.clear() on any Jwk instance, or mutating a collection obtained via jwk.entrySet().

Common situations: Attempting to add a 'kid' or custom claim to an already-parsed JWK; framework code that mutates maps generically; code ported from a mutable-map style.

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


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/6e1c266dc9f4a78a. Report an issue: GitHub.

Appendix: source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/AbstractJwk.java:245

    }

    @Override
    public Set<String> keySet() {
        return Collections.immutable(this.context.keySet());
    }

    @Override
    public Collection<Object> values() {
        return Collections.immutable(this.context.values());
    }

    @Override
    public Set<Entry<String, Object>> entrySet() {
        return Collections.immutable(this.context.entrySet());
    }

    private static Object immutable() {
        throw new UnsupportedOperationException(IMMUTABLE_MSG);
    }

    @Override
    public Object put(String s, Object o) {
        return immutable();
    }

    @Override
    public Object remove(Object o) {
        return immutable();
    }

    @Override
    public void putAll(Map<? extends String, ?> m) {
        immutable();
    }

    @Override

View on GitHub (pinned to fb71496164)