OAuth2 "invalid_client" client authentication failed in CI
The OAuth2 provider could not authenticate the client itself: the client_id is unknown, the client_secret is wrong, or the secret was sent in the body when the provider expects HTTP Basic auth. The response is 401 with "error":"invalid_client".
What this error means
A token request returns HTTP 401 with "error":"invalid_client" and often "Client authentication failed". Public flows work but the CI machine client is rejected.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="oauth"
{"error":"invalid_client","error_description":"Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)."}Common causes
Wrong or missing client_secret
The secret in the CI env does not match the registered client, or was never injected, so authentication fails.
Wrong client authentication method
The provider expects HTTP Basic (client_secret_basic) but the request sends the secret in the body (client_secret_post), or the reverse.
How to fix it
Send credentials the way the client is registered
- Check the app registration for its token endpoint auth method.
- For client_secret_basic, send client_id:client_secret as an Authorization: Basic header.
- For client_secret_post, send client_id and client_secret in the form body.
# client_secret_basic
curl -s -X POST "$TOKEN_URL" \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=client_credentialsConfirm the secret reached the step
A masked-but-empty secret produces invalid_client. Verify the secret is non-empty in the job without printing its value.
How to prevent it
- Store client_id and client_secret as CI secrets and inject them explicitly.
- Match the registered token endpoint auth method exactly.
- Rotate secrets in one place so CI and the provider stay in sync.