{"record":{"id":"f511a8e4b00f0e89","repo":"alibaba/nacos","slug":"failed-to-sign-payload","errorCode":null,"errorMessage":"Failed to sign payload","messagePattern":"Failed to sign payload","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/authenticate/AuthorizationCodeHandler.java","lineNumber":338,"sourceCode":"        }\n    }\n    \n    /**\n     * Sign a payload using HMAC-SHA256.\n     *\n     * @param payload the payload to sign\n     * @return base64-encoded signature\n     */\n    private String hmacSign(String payload) {\n        try {\n            Mac mac = Mac.getInstance(HMAC_ALGORITHM);\n            SecretKeySpec keySpec = new SecretKeySpec(\n                getSigningKey().getBytes(StandardCharsets.UTF_8), HMAC_ALGORITHM);\n            mac.init(keySpec);\n            byte[] signature = mac.doFinal(payload.getBytes(StandardCharsets.UTF_8));\n            return Base64.getUrlEncoder().withoutPadding().encodeToString(signature);\n        } catch (Exception e) {\n            throw new RuntimeException(\"Failed to sign payload\", e);\n        }\n    }\n    \n    /**\n     * Verify HMAC signature.\n     *\n     * @param payload   the original payload\n     * @param signature the signature to verify\n     * @return true if signature is valid\n     */\n    private boolean hmacVerify(String payload, String signature) {\n        String expectedSignature = hmacSign(payload);\n        return expectedSignature.equals(signature);\n    }\n    \n    /**\n     * Get the signing key for HMAC operations.\n     * Uses client secret as the signing key.","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/authenticate/AuthorizationCodeHandler.java#L320-L356","documentation":"A RuntimeException wrapping any exception thrown during HMAC-SHA256 signing of the OIDC state parameter. The underlying cause is attached. Most often it wraps an IllegalStateException from getSigningKey() (blank client secret), but it can also wrap JCE/InvalidKeyException failures.","triggerScenarios":"buildAuthorizationUrl or verifyAndDecodeState calls hmacSign, which calls getSigningKey() while client-secret is blank (the IllegalStateException is caught and rewrapped here), or the HmacSHA256 algorithm/provider is unavailable in the JVM.","commonSituations":"Authorization-code flow enabled without configuring client-secret; running in a FIPS/restricted JVM where HmacSHA256 is not available; a security manager blocking Mac.getInstance; client-secret config key typo.","solutions":["Inspect the wrapped cause exception — if it is 'Client secret is required for state signing', set nacos.plugin.auth.oidc.client-secret.","If the cause is NoSuchAlgorithmException/InvalidKeyException, check the JCE provider and JVM security policy (FIPS mode).","Ensure the client-secret config key is spelled exactly 'client-secret' and the value is non-blank.","Confirm HmacSHA256 is available: the default JDK provider supplies it, so this only fails in hardened/custom JVMs."],"exampleFix":"// before: authorization-code flow used with no client secret\nnacos.plugin.auth.oidc.client-id=myclient\n# client-secret missing\n// after\nnacos.plugin.auth.oidc.client-id=myclient\nnacos.plugin.auth.oidc.client-secret=s3cret-value","handlingStrategy":"validation","validationCode":"// Before starting the authorization-code flow, ensure a signing key is available\nif (StringUtils.isBlank(config.getClientSecret())) {\n    throw new IllegalStateException(\n        \"client-secret must be set for authorization-code state signing\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    String authUrl = handler.buildAuthorizationUrl(redirectUri);\n} catch (RuntimeException e) {\n    if (e.getMessage().equals(\"Failed to sign payload\")) {\n        Throwable cause = e.getCause();\n        // cause is typically IllegalStateException for blank client-secret\n        log.error(\"State signing failed: {}\", cause.getMessage());\n    }\n    throw e;\n}","preventionTips":["Always configure client-secret when enabling the authorization-code flow.","Fail fast at startup by asserting config.getClientSecret() is non-blank.","In restricted JVMs, verify HmacSHA256 availability via Mac.getInstance in a health check."],"tags":["oidc","crypto","authentication","authorization-code","config"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}