{"record":{"id":"4512cf7c9d3b61a3","repo":"jwtk/jjwt","slug":"wrap-nsa-jcaname-specifiedprovider-null","errorCode":null,"errorMessage":"wrap(nsa, jcaName, specifiedProvider, null)","messagePattern":"wrap\\(nsa, jcaName, specifiedProvider, null\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/JcaTemplate.java","lineNumber":402,"sourceCode":"\n                if (specifiedProvider == null && attempted == null) { // default provider doesn't support the alg name,\n                    // and we haven't tried BC yet, so try that now:\n                    Provider fallback = findBouncyCastle();\n                    if (fallback != null) { // BC found, try again:\n                        try {\n                            T value = doGet(jcaName, fallback);\n                            // record the successful attempt so we don't have to do this again:\n                            FALLBACK_ATTEMPTS.putIfAbsent(jcaName, Boolean.TRUE);\n                            return value;\n                        } catch (Throwable ignored) {\n                            // record the failed attempt so we don't keep trying and propagate original exception:\n                            FALLBACK_ATTEMPTS.putIfAbsent(jcaName, Boolean.FALSE);\n                        }\n                    }\n                }\n                // otherwise, we tried the fallback, or there isn't a fallback, so no need to try again, so\n                // propagate the exception:\n                throw wrap(nsa, jcaName, specifiedProvider, null);\n            } catch (Exception e) {\n                throw wrap(e, jcaName, specifiedProvider, null);\n            }\n        }\n\n        protected abstract T doGet(String jcaName, Provider provider) throws Exception;\n\n        // visible for testing:\n        protected Exception wrap(Exception e, String jcaName, Provider specifiedProvider, Provider fallbackProvider) {\n            String msg = \"Unable to obtain '\" + jcaName + \"' \" + getId() + \" instance from \";\n            if (specifiedProvider != null) {\n                msg += \"specified '\" + specifiedProvider + \"' Provider\";\n            } else {\n                msg += \"default JCA Provider\";\n            }\n            if (fallbackProvider != null) {\n                msg += \" or fallback '\" + fallbackProvider + \"' Provider\";\n            }","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/JcaTemplate.java#L384-L420","documentation":"JcaTemplate.get rethrows a NoSuchAlgorithmException (via wrap) after also attempting its fallback algorithm, when a JCA service cannot be found for the requested transformation/jcaName and provider. wrap converts it into a KeystoreException/SecurityException-style runtime error naming the algorithm and provider. It signals that the JVM (or the explicitly specified provider) offers no implementation of the required cryptographic service.","triggerScenarios":"Mac.getInstance / Cipher.getInstance / KeyPairGenerator.getInstance etc. for an algorithm like PBKDF2WithHmacSHA256, A128KW, or RS256's JCA name when the JRE or the provider passed in does not implement it, and the built-in fallback algorithm also fails.","commonSituations":"Running on FIPS-restricted JVMs, older JREs without newer algorithms (e.g. Ed25519 pre-JDK 15), IBM/SAP JDKs with different algorithm names, or specifying a Provider that does not offer the algorithm.","solutions":["Ensure the JRE supports the algorithm; install/register an appropriate JCA provider (e.g. BouncyCastle) and optionally specify it.","Do not pass a restricted 'specifiedProvider' that lacks the algorithm, or use the default provider search.","Check jjwt version — newer jjwt versions map algorithms to modern JCA names; upgrade if the JCA name changed.","Read the wrapped exception message to confirm the exact missing algorithm and add a provider for it."],"exampleFix":"// before\nProvider p = Security.getProvider(\"SunJCE\"); // lacks some algos\nMac mac = Jwts.SIG.HS256.mac.get(); // may wrap NoSuchAlgorithmException\n// after\nSecurity.addProvider(new BouncyCastleProvider());\nMac mac = Jwts.SIG.HS256.mac.get(); // fallback provider search succeeds","handlingStrategy":"fallback","validationCode":"try {\n    javax.crypto.Mac.getInstance(\"HmacSHA256\");\n} catch (NoSuchAlgorithmException e) {\n    Security.addProvider(new BouncyCastleProvider());\n}","typeGuard":null,"tryCatchPattern":"try {\n    Jwts.parser().verifyWith(key).build().parseSignedClaims(token);\n} catch (JwtException e) {\n    log.error(\"JCA algorithm unavailable: {}\", e.getMessage(), e.getCause());\n    throw new CryptoUnavailableException(e);\n}","preventionTips":["Test crypto availability on all target JVMs at startup","Register BouncyCastle when using newer algorithms on older JDKs","Avoid pinning a single provider that may lack the algorithm","Keep jjwt upgraded so JCA name mappings stay current"],"tags":["jca","crypto","nosuchalgorithm","jwt"],"backgroundTag":"unsupported-algorithm","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"}