GitHub Actions OIDC "Failed to get ID token"
A step asked GitHub for an OIDC ID token and the request failed. The usual cause is that the job never granted id-token: write (so the token endpoint is unavailable), but it can also be a transient failure of the token endpoint itself.
What this error means
A step that requests an OIDC token (cloud login, attestation, or a custom getIDToken call) fails with "Failed to get ID token" or a related OIDC request error, before any cloud credentials are exchanged.
Error: Failed to get ID token: Error message: Unable to get
ACTIONS_ID_TOKEN_REQUEST_URL env variable
Error: Could not fetch an OIDC token from the GitHub provider.Diagnose it: what token do you actually have?
Permission failures in Actions are almost never about your repository settings alone. Three things combine: the default GITHUB_TOKEN permission set for the repo or organization, the permissions: block in the workflow, and whether the event is a fork pull request, which downgrades the token to read-only regardless of everything else.
- name: Show the token scopes actually granted
run: |
curl -sI -H "Authorization: Bearer $GITHUB_TOKEN" \
https://api.github.com/ | grep -i "^x-oauth-scopes\|^x-accepted"
echo "event: ${{ github.event_name }}"
echo "fork PR: ${{ github.event.pull_request.head.repo.fork }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Common causes
Missing id-token: write permission
Without permissions: id-token: write on the job (or workflow), GitHub does not expose the OIDC request URL/token to the runner, so any token request fails immediately.
Default-permissions or org policy restricts the token
A restrictive default GITHUB_TOKEN permission set or an org/enterprise policy can withhold the id-token scope even when the workflow looks correct.
Transient OIDC token-endpoint failure
Occasionally the request to the GitHub OIDC token endpoint times out or returns a 5xx mid-job even though permissions are correct; the next attempt usually succeeds.
How to fix it
Grant id-token: write on the job
Add the id-token: write permission so GitHub exposes the OIDC request URL and token to the runner. Keep contents read unless the job needs more.
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/ci
aws-region: us-east-1Confirm org/enterprise policy allows the id-token scope
- Check that the org default workflow permissions are not blocking id-token.
- For reusable workflows, set id-token: write on the calling job so it propagates.
- Re-run after the permission is in place.
Retry a transient token-endpoint failure
- If permissions are correct and the failure is intermittent, re-run the job.
- For scripted token requests, wrap getIDToken in a short retry with backoff.
Grant the narrowest permission that works
Declaring a permissions: block switches the job from the repository default to exactly what you list, so an incomplete block is a common cause of a new failure right after someone tightened security. List every scope the job needs, not just the one that failed.
permissions:
contents: read # checkout
packages: write # push to GHCR
id-token: write # OIDC to a cloud provider
pull-requests: write # comment on or label a PR
checks: write # publish check runsHow to prevent it
- Set permissions: id-token: write explicitly on any job that uses OIDC.
- Keep org default permissions and reusable-workflow propagation in mind so the scope is never silently dropped.
- On Latchkey managed runners, transient OIDC token-endpoint timeouts and 5xx responses are retried automatically, so a one-off token-request blip does not fail the run.