jwtk/jjwt · error · IllegalStateException

A ${Key.class.getName()} or one or more name/value pairs mus

Error message

A ${Key.class.getName()} or one or more name/value pairs must be provided to create a JWK.

What it means

AbstractJwkBuilder.build() requires either a Key set on the context or at least one name/value pair (isEmpty() false). If neither is present it throws IllegalStateException because there is nothing from which to construct a JWK.

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/AbstractJwkBuilder.java:149

        Parameter<Set<KeyOperation>> param = Parameters.builder(KeyOperation.class)
                .setConverter(new KeyOperationConverter(registry)).set()
                .setId(AbstractJwk.KEY_OPS.getId())
                .setName(AbstractJwk.KEY_OPS.getName())
                .build();
        setDelegate(this.DELEGATE.parameter(param));
        return self();
    }

    @Override
    public J build() {

        //should always exist as there isn't a way to set it outside the constructor:
        Assert.stateNotNull(this.DELEGATE, "JwkContext should always be non-null");

        K key = this.DELEGATE.getKey();
        if (key == null && isEmpty()) {
            String msg = "A " + Key.class.getName() + " or one or more name/value pairs must be provided to create a JWK.";
            throw new IllegalStateException(msg);
        }

        try {
            this.opsPolicy.validate(this.DELEGATE.get(AbstractJwk.KEY_OPS));
            return jwkFactory.createJwk(this.DELEGATE);
        } catch (IllegalArgumentException iae) {
            //if we get an IAE, it means the builder state wasn't configured enough in order to create
            String msg = "Unable to create JWK: " + iae.getMessage();
            throw new MalformedKeyException(msg, iae);
        }
    }

    static class DefaultSecretJwkBuilder extends AbstractJwkBuilder<SecretKey, SecretJwk, SecretJwkBuilder>
            implements SecretJwkBuilder {
        public DefaultSecretJwkBuilder(JwkContext<SecretKey> ctx) {
            super(ctx);
            // assign a standard algorithm if possible:
            Key key = Assert.notNull(ctx.getKey(), "SecretKey cannot be null.");

View on GitHub (pinned to fb71496164)

Solutions

  1. Set key material: Jwks.builder().setKey(key).build().
  2. Provide JWK fields, e.g. Jwks.builder().put("kty","RSA").put("n",...).put("e",...).build().
  3. Check builder state with isEmpty()/getKey() before calling build().
  4. Catch IllegalStateException and surface a user-facing 'no key configured' message.

Example fix

// before
Jwk<?> jwk = Jwks.builder().build();
// after
Jwk<?> jwk = Jwks.builder().setKey(publicKey).build();
Defensive patterns

Strategy: validation

Validate before calling

if (builder.getKey() == null && builder.isEmpty()) { throw new IllegalStateException("No key or name/value pairs set for JWK"); }

Try / catch

try { Jwk<?> jwk = builder.build(); }
catch (IllegalStateException e) { throw new ConfigurationException("JWK not configured: " + e.getMessage()); }

Prevention

When it happens

Trigger: Calling Jwks.builder().build() without calling setKey/put for any JWK parameter — an entirely empty builder, e.g. Jwks.builder().build() bare.

Common situations: Forgot to set key material or fields like kty/n/e; builder constructed from an empty Map; refactoring removed the put calls; conditional code path skipped key assignment.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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