actions/deploy-pages "deployment failed" - Causes & Fix
actions/deploy-pages creates a deployment to the github-pages environment. Environment protection rules that the ref does not satisfy, missing pages/id-token permissions, or no uploaded Pages artifact all fail the deployment.
What this error means
A deploy-pages step fails creating or completing the deployment, sometimes citing the environment, a protection rule, or a missing artifact.
Error: Creating Pages deployment failed
Error: HttpError: Branch "feature/x" is not allowed to deploy to github-pages due to environment protection rules.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
Environment protection rule blocks the ref
The github-pages environment can restrict which branches may deploy; a non-allowed branch is rejected.
Missing permissions or artifact
Without pages: write and id-token: write, or without an uploaded Pages artifact, the deploy cannot complete.
How to fix it
Align environment, permissions, and artifact
- Allow the deploying branch in the github-pages environment rules.
- Set pages: write and id-token: write on the job and reference the environment.
- Ensure upload-pages-artifact ran before deploy-pages.
permissions:
pages: write
id-token: write
environment:
name: github-pages
steps:
- uses: actions/deploy-pages@v4Grant 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
- Configure the github-pages environment to allow your deploy branches.
- Keep the upload then deploy ordering intact.