Jira REST "401 Unauthorized" (API token basic auth) in CI
Jira Cloud rejects the call with 401 because it did not receive valid basic-auth credentials. Jira Cloud requires an Authorization: Basic base64(email:api_token) header, not your account password.
What this error means
A CI step calling the Jira REST API fails with HTTP 401 and a body like "Client must be authenticated to access this resource." Every request fails identically, not intermittently.
{"errorMessages":["Client must be authenticated to access this resource."],"errors":{}}
HTTP/1.1 401 UnauthorizedCommon causes
Using a password instead of an API token
Jira Cloud disabled basic auth with account passwords. Basic auth must be email:api_token base64-encoded, using a token created at id.atlassian.com.
The Authorization header is missing or unencoded
The secret was never injected into the step, or the email:token pair was sent raw instead of base64-encoded, so Jira sees no valid credential.
How to fix it
Send base64(email:api_token) as basic auth
- Create an API token at id.atlassian.com/manage-profile/security/api-tokens.
- Store the token as a CI secret and pass your account email alongside it.
- Base64-encode
email:tokenand send it in the Authorization header.
AUTH=$(printf '%s' "$JIRA_EMAIL:$JIRA_API_TOKEN" | base64 -w0)
curl -sf -H "Authorization: Basic $AUTH" \
-H "Accept: application/json" \
"https://your-domain.atlassian.net/rest/api/3/myself"Let curl encode the credentials
Passing -u email:token lets curl build the header, avoiding a hand-rolled base64 mistake.
curl -sf -u "$JIRA_EMAIL:$JIRA_API_TOKEN" \
"https://your-domain.atlassian.net/rest/api/3/myself"How to prevent it
- Store the API token (never a password) in CI secrets and inject it per step.
- Use
-u email:tokenor base64-encode the exactemail:tokenpair. - Verify auth with a cheap
/myselfcall before the real request.