apereo/cas · error · CredentialsException

Client Credentials provided is not valid for registered…

Error message

Client Credentials provided is not valid for registered service: 

What it means

Thrown when the extracted client_secret fails the registered service's secret validation. The client_id resolved to a registered OAuth service (and access was allowed), but the provided secret does not match the configured one, so the credentials are rejected.

Solutions

  1. Verify the client_secret sent matches the secret configured on the registered OAuth service and redeploy/reload the service registry if it changed
  2. Re-send credentials via HTTP Basic auth (base64(client_id:client_secret)) ensuring correct encoding without stray whitespace
  3. Check the registered service's name in the error against the service you think you are calling — the client_id may resolve to a different registered service than expected
  4. If secrets are encrypted, confirm the encryption key/secret configuration used by the service registry matches what was used when storing

Example fix

// before
Authorization: Basic base64("myclient:userpassword")
// after
Authorization: Basic base64("myclient:configuredClientSecret")
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await casLogin({ clientId, clientSecret });
} catch (e) {
  if (String(e.message).startsWith('Client Credentials provided is not valid')) {
    // reload secret from secret store / alert on rotation mismatch
  }
}

Prevention

When it happens

Trigger: Request carries a client_id that resolves to a registered service but the accompanying client_secret (form param or basic auth) is wrong, stale after rotation, or compared against a service whose secret was recently changed in the service registry.

Common situations: Environment mismatch (staging secret used against production); secrets rotated in the service registry JSON/YAML but not in the client; whitespace/encoding issues in the secret; client configured with the end-user password instead of the client secret.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/3170dd5ee002155e. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-oauth-core-api/src/main/java/org/apereo/cas/support/oauth/authenticator/OAuth20UsernamePasswordAuthenticator.java:81

    private final ConfigurableApplicationContext applicationContext;

    @Override
    public Optional<Credentials> validate(final CallContext callContext, final Credentials credentials) throws CredentialsException {
        try {
            val upc = (UsernamePasswordCredentials) credentials;
            val casCredential = new UsernamePasswordCredential(upc.getUsername(), upc.getPassword());
            val clientIdAndSecret = requestParameterResolver.resolveClientIdAndClientSecret(callContext);
            if (StringUtils.isBlank(clientIdAndSecret.getKey())) {
                throw new CredentialsException("No client credentials could be identified in this request");
            }

            val clientId = clientIdAndSecret.getKey();
            val registeredService = OAuth20Utils.getRegisteredOAuthServiceByClientId(servicesManager, clientId);
            RegisteredServiceAccessStrategyUtils.ensureServiceAccessIsAllowed(registeredService);

            val clientSecret = clientIdAndSecret.getRight();
            if (!clientSecretValidator.validate(registeredService, clientSecret)) {
                throw new CredentialsException("Client Credentials provided is not valid for registered service: "
                    + Objects.requireNonNull(registeredService).getName());
            }
            val redirectUri = requestParameterResolver.resolveRequestParameter(callContext.webContext(), OAuth20Constants.REDIRECT_URI)
                .map(String::valueOf).orElse(StringUtils.EMPTY);
            OAuth20Utils.validateRedirectUri(redirectUri, true);
            val service = StringUtils.isNotBlank(redirectUri)
                ? webApplicationServiceFactory.createService(redirectUri)
                : webApplicationServiceFactory.createService(clientId);
            service.getAttributes().put(OAuth20Constants.CLIENT_ID, CollectionUtils.wrapList(clientId));
            service.getAttributes().put(OAuth20Constants.REDIRECT_URI, CollectionUtils.wrapList(redirectUri));

            val authenticationResult = authenticationSystemSupport.finalizeAuthenticationTransaction(service, casCredential);
            if (authenticationResult == null) {
                throw new CredentialsException("Could not authenticate the provided credentials");
            }

            val principal = buildAuthenticatedPrincipal(authenticationResult, registeredService, service, callContext);
            val profile = new CommonProfile();

View on GitHub (pinned to e7288fc434)