alibaba/nacos · error · IllegalStateException
Client secret is required for state signing
Error message
Client secret is required for state signing
What it means
Thrown by getSigningKey() when the configured client-secret is blank. The OIDC authorization-code flow reuses the client secret as the HMAC key to sign the self-contained state parameter (nonce.expirationTime.signature). Without it, CSRF state protection cannot operate.
Source
Thrown at plugin-default-impl/nacos-oidc-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/oidc/authenticate/AuthorizationCodeHandler.java:363
* @param payload the original payload
* @param signature the signature to verify
* @return true if signature is valid
*/
private boolean hmacVerify(String payload, String signature) {
String expectedSignature = hmacSign(payload);
return expectedSignature.equals(signature);
}
/**
* Get the signing key for HMAC operations.
* Uses client secret as the signing key.
*
* @return signing key
*/
private String getSigningKey() {
String clientSecret = config.getClientSecret();
if (StringUtils.isBlank(clientSecret)) {
throw new IllegalStateException("Client secret is required for state signing");
}
return clientSecret;
}
/**
* Build logout URL for RP-initiated logout.
*
* @param idToken ID token for logout hint
* @param redirectUri post-logout redirect URI
* @return logout URL or null if not supported
*/
public String buildLogoutUrl(String idToken, String redirectUri) {
String endSessionEndpoint;
try {
endSessionEndpoint = metadataProvider.getMetadata().getEndSessionEndpoint();
} catch (Exception e) {
LOGGER.warn("Failed to discover OIDC logout endpoint: {}", e.getMessage());
return null;View on GitHub (pinned to 9b989acdf1)
Solutions
- Set nacos.plugin.auth.oidc.client-secret to a non-blank value matching the IdP client registration.
- If using a public/PKCE-only client with no secret, this built-in handler does not support it — register a confidential client with the IdP instead.
- Verify the config map actually delivers the secret (check OidcAuthPluginConfig.getClientSecret()).
Example fix
// before nacos.plugin.auth.oidc.client-id=public-client // no client-secret configured // after: register a confidential client and supply its secret nacos.plugin.auth.oidc.client-id=confidential-client nacos.plugin.auth.oidc.client-secret=generated-secret
Defensive patterns
Strategy: validation
Validate before calling
// Validate at startup that the authorization-code flow can sign state
if (config.isJwtValidation() /* or auth-code flow enabled */
&& StringUtils.isBlank(config.getClientSecret())) {
throw new IllegalStateException(
"client-secret is required for OIDC authorization-code flow");
} Prevention
- Treat a blank client-secret as a fatal config error when the auth-code flow is enabled.
- Register a confidential (not public) OIDC client with the IdP.
- Add a startup assertion that fails the context if client-secret is missing.
When it happens
Trigger: buildAuthorizationUrl() or verifyAndDecodeState() runs while config.getClientSecret() returns blank — i.e. the authorization-code login flow is active but client-secret was never set.
Common situations: Public (PKCE-only) OIDC client that legitimately has no secret but the built-in handler requires one; client-secret key mistyped; secret intentionally left blank during testing; migrating from a flow that didn't need signing.
Related errors
- Token endpoint not configured
- Failed to sign payload
- Token exchange failed:
- Authorization endpoint not configured
- Nonce not present in ID token. Set 'nacos.plugin.auth.oidc.s
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/616243102038104c.
Report an issue: GitHub.