{"record":{"id":"24411f7513a9ad42","repo":"karatelabs/karate","slug":"failed-to-generate-code-challenge","errorCode":null,"errorMessage":"Failed to generate code challenge","messagePattern":"Failed to generate code challenge","errorType":"exception","errorClass":"OAuth2Exception","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/http/PkceGenerator.java","lineNumber":64,"sourceCode":"        byte[] bytes = new byte[32];\n        random.nextBytes(bytes);\n        return base64UrlEncode(bytes);\n    }\n\n    /**\n     * Generate code challenge from verifier\n     */\n    private static String generateCodeChallenge(String verifier, String method) {\n        if (\"plain\".equals(method)) {\n            return verifier;\n        }\n        if (\"S256\".equals(method)) {\n            try {\n                MessageDigest digest = MessageDigest.getInstance(\"SHA-256\");\n                byte[] hash = digest.digest(verifier.getBytes(StandardCharsets.US_ASCII));\n                return base64UrlEncode(hash);\n            } catch (Exception e) {\n                throw new OAuth2Exception(\"Failed to generate code challenge\", e);\n            }\n        }\n        throw new IllegalArgumentException(\"Unsupported PKCE method: \" + method);\n    }\n\n    /**\n     * Base64-URL encoding without padding\n     */\n    private static String base64UrlEncode(byte[] data) {\n        return Base64.getUrlEncoder()\n            .withoutPadding()\n            .encodeToString(data);\n    }\n\n    public String getVerifier() { return verifier; }\n    public String getChallenge() { return challenge; }\n    public String getMethod() { return method; }\n}","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/http/PkceGenerator.java#L46-L82","documentation":"PkceGenerator throws this wrapped OAuth2Exception when the SHA-256 code-challenge computation fails for an S256 PKCE flow. It wraps any Exception from MessageDigest.getInstance(\"SHA-256\") or digesting, which on a normal JVM should never occur since SHA-256 is mandatory for every JRE. The underlying cause is attached as the exception's cause.","triggerScenarios":"Calling PkceGenerator.challenge(verifier, \"S256\") (via generateCodeChallenge) in a JVM environment where the SHA-256 MessageDigest algorithm is not available from the configured security provider — e.g. a stripped-down/custom JRE, a broken JCE provider registration, or a security policy restricting crypto algorithms.","commonSituations":"Running Karate on hardened FIPS-only JVMs where SHA-256 is mapped to a different name; custom or removed java.security security providers; severely pruned runtime images (custom jlink builds missing crypto modules).","solutions":["Inspect the exception's cause (getCause()) to identify the actual NoSuchProviderException/NoSuchAlgorithmException.","Verify the JVM's security providers include one supplying SHA-256 (check java.security file and Security.getProviders()).","Restore or register a standard provider (e.g.SUN) in java.security or via Security.insertProviderAt().","If using a jlink/pruned runtime, include the jdk.crypto.ec / crypto modules.","As a last resort use PKCE method \"plain\" if the authorization server supports it."],"exampleFix":"// before (stripped runtime)\njava --list-modules  // jdk.crypto.ec missing\n// after\njlink --add-modules java.base,jdk.crypto.ec --output custom-runtime","handlingStrategy":"try-catch","validationCode":"// Java\nboolean ok = false;\ntry { MessageDigest.getInstance(\"SHA-256\"); ok = true; } catch (Exception ignored) {}","typeGuard":null,"tryCatchPattern":"try {\n    String challenge = PkceGenerator.challenge(verifier, \"S256\");\n} catch (OAuth2Exception e) {\n    logger.error(\"PKCE crypto failure\", e.getCause());\n    throw new IllegalStateException(\"JVM lacks SHA-256 support\", e);\n}","preventionTips":["Use standard, unmodified JRE distributions","Test crypto availability at app startup","Avoid stripping crypto modules from jlink images","Log the wrapped cause for diagnostics"],"tags":["oauth2","pkce","crypto","jvm"],"backgroundTag":"missing-dependency","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}