{"record":{"id":"7dbd0790626aedce","repo":"apereo/cas","slug":"jwt-string-claim-is-missing-or-invalid","errorCode":null,"errorMessage":"JWT string claim is missing or invalid","messagePattern":"JWT string claim is missing or invalid","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-oidc-vc/src/main/java/org/apereo/cas/vc/presentation/OidcVerifiableCredentialPresentationResponseEndpointController.java","lineNumber":470,"sourceCode":"        }\n    }\n\n    private static List<String> readAudience(final Map<String, Object> claims) {\n        val audience = claims.get(\"aud\");\n        if (audience instanceof final String value) {\n            return List.of(value);\n        }\n        if (audience instanceof final List<?> values\n            && values.stream().allMatch(String.class::isInstance)) {\n            return values.stream().map(String.class::cast).toList();\n        }\n        throw new IllegalArgumentException(\"JWT audience is invalid\");\n    }\n\n    private static String requiredStringClaim(final Map<String, Object> claims, final String name) {\n        val value = claims.get(name);\n        if (!(value instanceof final String stringValue) || stringValue.isBlank()) {\n            throw new IllegalArgumentException(\"JWT string claim is missing or invalid\");\n        }\n        return stringValue;\n    }\n\n    private static boolean constantTimeEquals(final String left, final String right) {\n        return MessageDigest.isEqual(left.getBytes(StandardCharsets.UTF_8), right.getBytes(StandardCharsets.UTF_8));\n    }\n\n    private static ResponseEntity<Map<String, Object>> buildResponse(final HttpStatus status,\n                                                                     final Map<String, Object> body) {\n        return ResponseEntity.status(status)\n            .cacheControl(CacheControl.noStore())\n            .header(HttpHeaders.PRAGMA, \"no-cache\")\n            .body(body);\n    }\n\n    private static void require(final boolean condition, final String message) {\n        if (!condition) {","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-oidc-vc/src/main/java/org/apereo/cas/vc/presentation/OidcVerifiableCredentialPresentationResponseEndpointController.java#L452-L488","documentation":"requiredStringClaim extracts a named JWT claim and requires it to be a non-blank String. Called by issuer, credentialType, clientId, and validateKeyBindingJwt, it throws IllegalArgumentException when the claim is missing, not a string, or blank.","triggerScenarios":"Key-binding JWT or credential-response JWT lacks a required claim (iss, credential type, client_id, nonce, etc.), or the claim value is null, a non-string type, or an empty/whitespace string.","commonSituations":"Clients omitting required claims when building the key-binding JWT; empty-string claims from misconfigured clients; claim name typos producing null lookups.","solutions":["Add the required claim with a non-blank string value before signing the JWT","Check which claim failed (iss/clientId/credentialType) via the call site and inspect the token payload in a JWT decoder","Fix client configuration that leaves the claim empty (e.g. unconfigured client_id)"],"exampleFix":"// before\nclaims.setStringClaim(\"client_id\", \"\"); // blank\n// after\nclaims.setStringClaim(\"client_id\", \"my-client\"); // non-blank string","handlingStrategy":"validation","validationCode":"boolean hasClaim(Map<String,Object> claims, String name) {\n  Object v = claims.get(name);\n  return v instanceof String s && !s.isBlank();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check required claim presence before signing JWTs","Avoid blank-string defaults in client config","Log claim names during development to catch typos"],"tags":["jwt","claims","validation","missing-claim"],"backgroundTag":"missing-required-argument","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}