Skip to content
Latchkey

GitHub Actions "Input required and not supplied: token"

An action declared token as a required input, but it arrived empty - usually a secret that does not exist, is named wrong, or was not passed to a reusable workflow.

What this error means

An action fails at startup with "Input required and not supplied: token". The action never runs because its required token input resolved to an empty string.

Actions log
Error: Input required and not supplied: token

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.

.github/workflows/ci.yml
- 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

Secret missing or misnamed

with: token: ${{ secrets.MY_TOKEN }} resolves to empty when the secret does not exist or is spelled differently than defined.

Secret not passed to a reusable workflow or fork

A reusable workflow only sees secrets explicitly passed (or inherited). On a fork pull_request, secrets are unavailable, so the token input is empty.

How to fix it

Supply a real token input

Pass a defined secret (or the built-in GITHUB_TOKEN) to the action’s token input.

.github/workflows/ci.yml
- uses: some/action@v1
  with:
    token: ${{ secrets.GITHUB_TOKEN }}

Make sure the secret reaches the job

  1. Confirm the secret name matches exactly what is stored in repo/org/environment settings.
  2. For reusable workflows, forward the secret via the secrets: block or secrets: inherit.
  3. Remember fork pull_request runs get no secrets - gate token-using steps accordingly.

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.

.github/workflows/ci.yml
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 runs

How to prevent it

  • Reference secret names exactly as defined.
  • Forward secrets explicitly to reusable workflows.
  • Guard token-dependent steps so fork PRs do not run them with empty secrets.

Frequently asked questions

What causes GitHub Actions "Input required and not supplied: token"?
There are 2 common causes: secret missing or misnamed and secret not passed to a reusable workflow or fork. with: token: ${{ secrets.MY_TOKEN }} resolves to empty when the secret does not exist or is spelled differently than defined.
How do I fix GitHub Actions "Input required and not supplied: token"?
There are 2 fixes depending on which cause you have: supply a real token input and make sure the secret reaches the job. Work through them in order, since the first is the most common.
What does GitHub Actions "Input required and not supplied: token" actually mean?
An action fails at startup with "Input required and not supplied: token".
How do I stop GitHub Actions "Input required and not supplied: token" happening again?
Reference secret names exactly as defined. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card