{"record":{"id":"5cdb339f6c3f8b4a","repo":"jwtk/jjwt","slug":"unrelated-key-operations-are-not-allowed-keyopera","errorCode":null,"errorMessage":"Unrelated key operations are not allowed. KeyOperation [${inner}] is unrelated to [${operation}].","messagePattern":"Unrelated key operations are not allowed\\. KeyOperation \\[(.+?)\\] is unrelated to \\[(.+?)\\]\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/DefaultKeyOperationPolicy.java","lineNumber":51,"sourceCode":"        Assert.notEmpty(ops, \"KeyOperation collection cannot be null or empty.\");\n        this.ops = Collections.immutable(ops);\n        this.allowUnrelated = allowUnrelated;\n    }\n\n    @Override\n    public Collection<KeyOperation> getOperations() {\n        return this.ops;\n    }\n\n    @Override\n    public void validate(Collection<? extends KeyOperation> ops) {\n        if (allowUnrelated || Collections.isEmpty(ops)) return;\n        for (KeyOperation operation : ops) {\n            for (KeyOperation inner : ops) {\n                if (!operation.isRelated(inner)) {\n                    String msg = \"Unrelated key operations are not allowed. KeyOperation [\" + inner +\n                            \"] is unrelated to [\" + operation + \"].\";\n                    throw new IllegalArgumentException(msg);\n                }\n            }\n        }\n    }\n\n    @Override\n    public int hashCode() {\n        int hash = Boolean.valueOf(this.allowUnrelated).hashCode();\n        KeyOperation[] ops = this.ops.toArray(new KeyOperation[0]);\n        hash = 31 * hash + Objects.nullSafeHashCode((Object[]) ops);\n        return hash;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj == this) return true;\n        if (!(obj instanceof DefaultKeyOperationPolicy)) {\n            return false;","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/DefaultKeyOperationPolicy.java#L33-L69","documentation":"IllegalArgumentException from DefaultKeyOperationPolicy.validate when a set of KeyOperations contains operations that are unrelated to each other and the policy does not allow unrelated operations. JWK key_ops entries must be mutually related (e.g. all encryption-direction operations).","triggerScenarios":"Building a JWK with keyOps containing unrelated operations, e.g. KeyOperations.ENCRYPT combined with KeyOperations.VERIFY, while the policy's allowUnrelated flag is false.","commonSituations":"Copying key_ops values from multiple different keys into one; typo'ing or mixing encrypt/decrypt-direction and sign/verify-direction operations; programmatically aggregating permitted operations from several sources.","solutions":["Restrict the JWK's keyOps set to related operations (e.g. only ENCRYPT/DECRYPT or only SIGN/VERIFY).","Create the policy with allowUnrelated=true if you intentionally permit unrelated combinations.","Validate the operation list against KeyOperation.isRelated pairs before building the key.","Fix the source of aggregated operations so unrelated ones are not merged into one key."],"exampleFix":"// before\nJwts.builder().keys().builder()\n  .keyOperations(EnumSet.of(KeyOperation.ENCRYPT, KeyOperation.SIGN)).build();\n// after\nJwts.builder().keys().builder()\n  .keyOperations(EnumSet.of(KeyOperation.ENCRYPT, KeyOperation.DECRYPT)).build();","handlingStrategy":"validation","validationCode":"boolean allRelated(Set<KeyOperation> ops) {\n    for (KeyOperation a : ops) for (KeyOperation b : ops)\n        if (!a.isRelated(b)) return false;\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n    builder.keyOperations(ops);\n} catch (IllegalArgumentException e) {\n    logger.error(\"Unrelated key_ops: {}\", e.getMessage());\n    ops = relatedSubset(ops); // e.g. keep only encryption-direction ops\n}","preventionTips":["Group operations by direction: {encrypt,decrypt,wrapKey,unwrapKey} vs {sign,verify}","Never merge key_ops sets from different keys","Build operation sets from named constants per key purpose"],"tags":["java","jjwt","jwk","key-operations","validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}