I lost every 2FA method on my GitHub account. Web login has been dead since August. gh in the terminal still pushed fine, so I kept putting it off. This time I tried everything.
The way out was on a server: an SSH key I registered to my account back in May while setting up a side-project server. I put it there and forgot about it. It got my recovery request through, and GitHub is still reviewing it.
What didn't work
- 2FA app: I wiped and sold the phone in July
- Recovery codes: GitHub's emails show I viewed them in March. I couldn't find where I saved them
- Passkey: it lived in Edge on a Windows laptop. The laptop is gone
-
ghtoken: the recovery docs only list personal access tokens you create yourself. Theghlogin token isn't on the list - Old PATs: expired, or I don't know where they are
- A recovery request in August: submitted, still locked out
I almost gave up on the account
Moving my repos to a new account changes the GitHub Pages URLs, which would break links I'd already submitted to contests. And contributions follow the commit email, which is tied to the locked account.
You can unlink just the email address from a locked account, then add that email to a new account and keep your commit history. But you can't undo it. I kept that as a last resort.
In the meantime I pulled all 22 repos with git clone --mirror.
It was on the server
GitHub account recovery asks for one more thing after email verification: a device you've signed in with before, an SSH key you registered before, or a PAT you created before. My account had one SSH key registered, and it didn't match any key on my Mac.
Digging through GitHub's security emails, I found "A new SSH authentication public key was added to your account", sent the day I set up that server in May. I wanted the server to pull from a private repo, so I generated a key on the server and added it straight to my account. In June I switched to a repo-only deploy key and never removed the old one.
Why did I even put it there? It saved me, though.
That key got me through the SSH verification step of the recovery request. Now I'm waiting for GitHub to review it.
If you want to check yours
The easiest way is to hand it to an AI agent. That's how I found mine, with Claude Code. Something like this:
I lost 2FA on my GitHub account (<username>) and can't log in on the web. Find an "SSH key previously registered to the account" that I can use for recovery. 1. Get the fingerprints of keys registered to the account from https://github.com/<username>.keys 2. Compare them with the ~/.ssh key fingerprints on this machine and on servers I can reach 3. If nothing matches, search my email for GitHub "SSH key was added" alerts to see when and where it was registered 4. If you find it, check that ssh -i <key> -o IdentitiesOnly=yes -T git@github.com says "Hi <username>!" Don't print private keys or tokens. Only show locations and fingerprints. Ask me before connecting to any server. To do it by hand:
Fingerprints of keys registered to your account:
curl -s https://github.com/<username>.keys | ssh-keygen -lf - Find a matching key on each machine you have (servers included):
for k in ~/.ssh/*; do fp=$(ssh-keygen -y -P "" -f "$k" 2>/dev/null | ssh-keygen -lf - 2>/dev/null | awk '{print $2}') [ -n "$fp" ] && echo "$fp $k" done | grep -F "$(curl -s https://github.com/<username>.keys | ssh-keygen -lf - | awk '{print $2}')" Then check it. Hi <username>! means you can use it. Hi <username>/<repo>! means it's a repo-only deploy key, which won't work.
ssh -i <path to key> -o IdentitiesOnly=yes -T git@github.com Worth checking now
- Do you know where your recovery codes are?
- Is your passkey on only one device?
- Have you ever put an account-level SSH key on a server?



