Repository navigation
Troubleshooting
This page covers the most common problems encountered when running GitHub Mirror Backup.
The script performs several independent operations:
GitHub API
↓
Repository discovery
↓
SSH authentication
↓
Git mirror clone/update
↓
Local storage
The first step is therefore to identify which layer is failing.
SSH is used to access the actual Git repositories.
Test it directly:
ssh -T git@github.comA successful authentication looks similar to:
Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access.
This message is normal. GitHub does not provide shell access through this endpoint.
Example:
git@github.com: Permission denied (publickey).
Check whether an SSH key exists:
ls -la ~/.ssh/Check which keys SSH is attempting to use:
ssh -vT git@github.comLook for lines containing:
Offering public key
Server accepts key
If necessary, explicitly configure the key in:
~/.ssh/config
Example:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Then test again:
ssh -T git@github.comThe script compares the GitHub account returned by the API with the account authenticated through SSH.
For example:
API account csiber
SSH account another-user
This produces a warning.
The SSH key may belong to a different GitHub account, so that account may not have access to all repositories discovered through the API token.
Fix the SSH key configuration or register the correct public key with the correct GitHub account.
The Personal Access Token is used for repository discovery.
Check that the token file exists:
ls -l ~/.config/github/tokenRecommended permissions:
chmod 600 ~/.config/github/tokenThe token should contain one token on one line.
curl -fsSL \
-H "Authorization: Bearer $(cat ~/.config/github/token)" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/userA successful request returns JSON containing the authenticated account.
If the request returns an authentication error, check:
- token is still valid
- token has not expired
- token has sufficient repository permissions
- token belongs to the expected GitHub account
Typical API response:
401 Unauthorized
Create a new token and replace the contents of:
~/.config/github/token
Then test the API again.
Do not put the new token into the script itself.
If the API works but some repositories are not discovered, check the token's permissions and the account's actual access to those repositories.
The script queries repositories associated with:
owner
collaborator
organization member
It cannot back up repositories to which the authenticated account has no access.
There are two separate network connections to GitHub.
api.github.com
github.com:22
Test basic HTTPS connectivity:
curl -I https://api.github.comTest GitHub SSH:
ssh -T git@github.comIf HTTPS works but SSH fails, the problem is likely related to:
- firewall rules
- outbound TCP/22 filtering
- DNS
- SSH configuration
- network routing
Some networks block outbound SSH.
GitHub also provides SSH access through port 443.
However, the backup script currently uses the normal GitHub SSH endpoint. If your network blocks TCP/22, configure OpenSSH to use GitHub's SSH-over-443 endpoint.
For example:
Host github.com
HostName ssh.github.com
Port 443
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Test:
ssh -T git@github.comThe same configuration is then automatically used by Git because the script uses SSH URLs.
Permission problems can occur locally even when GitHub authentication is working.
Check:
ls -ld /path/to/backupTest writing:
touch /path/to/backup/.write-test
rm /path/to/backup/.write-testIf this fails, the user running the script does not have sufficient permissions.
Fix the ownership or permissions of the backup directory.
For example:
sudo chown -R backupuser:backupuser /path/to/backupUse the appropriate user and group for your system.
Check:
ls -l ~/.config/github/tokenThe file should normally look similar to:
-rw------- 1 user user ... token
If necessary:
chmod 600 ~/.config/github/tokenRemember that scheduled tasks may run as a different user than interactive shell sessions.
A token located under:
/home/csiber/.config/github/token
will not automatically be available to a scheduled task running as another account.
Existing repositories are updated with:
git remote update --pruneIf this fails, test the mirror manually.
First check the repository:
git --git-dir=/path/to/repository.git rev-parse --is-bare-repositoryExpected:
true
Check the configured remote:
git --git-dir=/path/to/repository.git remote -vIt should point to the expected GitHub SSH URL.
Example:
origin git@github.com:owner/repository.git (fetch)
origin git@github.com:owner/repository.git (push)
Test the remote:
git --git-dir=/path/to/repository.git ls-remote originIf this fails, the problem is usually SSH authentication, repository permissions or network connectivity.
You can run:
git --git-dir=/path/to/repository.git remote update --pruneThis is the same operation used by the backup script for an existing mirror.
If it succeeds manually but fails through the scheduler, compare the execution environment.
In particular, check:
- user account
$HOME- SSH key location
- SSH configuration
- token file location
- mounted backup storage
A repository may disappear from the GitHub API because it was:
- deleted
- renamed
- transferred
- made inaccessible to the authenticated account
The script does not automatically delete the local mirror.
Instead it reports it as an orphaned mirror.
Example:
ORPHANED MIRRORS
! old-project.git
The local copy is intentionally preserved.
Do not delete it automatically unless you have confirmed that it is no longer needed.
Check available space:
df -h /path/to/backupCheck which repositories consume the most space:
du -sh /path/to/backup/*.git | sort -hA GitHub repository's reported API size is only an estimate. The actual local mirror size can differ significantly because Git objects, history and other repository data may not correspond directly to the displayed GitHub size.
The first full mirror run can also temporarily generate significant disk activity.
If the script reports:
fetch failed
inspect the repository manually:
git --git-dir=/path/to/repository.git fsckCheck its remotes:
git --git-dir=/path/to/repository.git remote -vCheck its refs:
git --git-dir=/path/to/repository.git show-refDo not immediately delete a failed mirror.
Investigate the cause first.
If the local mirror is genuinely damaged and the GitHub repository is still accessible, it can be recreated after preserving the old copy.
A very common source of confusion is:
Works manually
↓
Fails in Task Scheduler
Scheduled jobs often have a different environment.
Check the following:
whoami
echo "$HOME"
echo "$PATH"The scheduled task should run as the same user that has:
- the GitHub token
- the SSH private key
- access to the backup directory
Use absolute paths where practical.
The backup script itself already uses explicit paths for the backup destination and token file, which reduces environment-related problems.
Every execution creates a log under:
_logs/
Example:
_logs/github-backup-2026-09-28_08-00-00.log
The log contains the same operational information displayed in the terminal, but without ANSI color escape sequences.
For a quick look at failures:
grep -A6 -B2 "FAILED" /path/to/backup/_logs/*.logFor the latest log:
ls -1t /path/to/backup/_logs/github-backup-*.log | head -1Then:
less "$(ls -1t /path/to/backup/_logs/github-backup-*.log | head -1)"When something fails, run these in order:
# 1. GitHub API
curl -fsSL \
-H "Authorization: Bearer $(cat ~/.config/github/token)" \
https://api.github.com/user
# 2. SSH
ssh -T git@github.com
# 3. GitHub repository access
git ls-remote git@github.com:OWNER/REPOSITORY.git
# 4. Local storage
df -h /path/to/backup
# 5. Local permissions
ls -ld /path/to/backup
# 6. Mirror state
git --git-dir=/path/to/repository.git remote -vIf all six work, the backup engine itself should normally be able to discover and mirror the repository.
Backup failed
│
├── API fails?
│ └── Check token / GitHub API / network
│
├── SSH fails?
│ └── Check SSH key / account / network
│
├── ls-remote fails?
│ └── Check repository permissions / SSH
│
├── Local write fails?
│ └── Check NAS permissions / disk space
│
└── Only scheduled execution fails?
└── Check user / HOME / SSH environment
When reporting a problem, include the relevant error from the backup log, but never include the GitHub Personal Access Token or private SSH key.