Skip to content
Latchkey

MkDocs gh-deploy "Permission denied" pushing gh-pages in CI

mkdocs gh-deploy built the site and tried to push it to the gh-pages branch, but the git push was rejected. The CI token does not have write permission to the repository contents.

What this error means

mkdocs gh-deploy fails at the push step with "remote: Permission to OWNER/REPO.git denied" or "The requested URL returned error: 403", after building successfully.

mkdocs
remote: Permission to acme/docs.git denied to github-actions[bot].
fatal: unable to access 'https://github.com/acme/docs.git/': The requested URL returned error: 403
Error: Process completed with exit code 128.

Common causes

The workflow token lacks contents: write

The default GITHUB_TOKEN is read-only unless the workflow grants permissions: contents: write, so the push to gh-pages is rejected.

Checkout did not persist credentials for the push

Without credentials configured for the git remote, gh-deploy cannot authenticate the push.

How to fix it

Grant write permission to the job

  1. Add permissions: contents: write to the workflow or job.
  2. Use mkdocs gh-deploy --force from a checkout with token credentials.
  3. Re-run; the push to gh-pages now authenticates.
.github/workflows/docs.yml
permissions:
  contents: write

# step
- run: mkdocs gh-deploy --force

Use a token with push rights

If pushing to another repo or a protected branch, configure a token or deploy key that has write access to that target.

How to prevent it

  • Set permissions: contents: write for deploy jobs.
  • Confirm checkout persists credentials for the push.
  • Use a token or deploy key scoped to the target when it is not the same repo.

Frequently asked questions

What causes ""Permission to ... denied""?
The default GITHUB_TOKEN is read-only unless the workflow grants permissions: contents: write, so the push to gh-pages is rejected.
How do I fix "Permission to ... denied"?
Grant write permission to the job

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card