Fix GitHub CLI NO_PUBKEY / EXPKEYSIG Errors After the September 2026 Key Rotation

Fix GitHub CLI NO_PUBKEY / EXPKEYSIG Errors After the September 2026 Key Rotation

If apt update, dnf update gh, or yum update gh suddenly started failing on a Linux box that has the GitHub CLI installed from GitHub's own package repository, you're not imagining it. The PGP key GitHub CLI used to sign its Linux packages and repository metadata expired on September 5, 2026, and any system that hadn't picked up the replacement key by then starts throwing signature verification failures on every package operation โ€” not just gh upgrades.

Why this happens

GitHub CLI's apt/dnf/yum/zypper repositories are signed. Every time you run a package manager command, it checks the repo metadata (and the .deb/.rpm files themselves) against a known public key stored locally in your keyring. GitHub published a replacement key back on April 8, 2026, and the repo metadata has been signed with both the old and new key since then โ€” so if you installed or updated gh any time after that date using the official instructions, you already have the new key and none of this affects you.

The problem hits systems that:

  • Installed gh from the official apt/rpm repo before April 8, 2026, and
  • Never re-ran the install/setup steps since, so the local keyring still only has the old key

Once the old key formally expired on September 5, 2026, GPG (correctly) stops trusting anything signed only with it โ€” and because the repository metadata itself is what's unverifiable, the failure isn't limited to gh โ€” a plain apt update on an affected Debian/Ubuntu box will report an error against the whole cli.github.com repo entry until it's fixed.

Errors you'll actually see

Depending on distro and package manager, the exact message varies:

1Failed to fetch https://cli.github.com/packages/... EXPKEYSIG 23F3D4EA75716059
1The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 5612B36462313325
1Warning: File 'repomd.xml' from repository 'gh-cli' is signed with an unknown key
1Certificate for key ... is invalid: certificate is not alive. Expired on 2026-09-05

If you see any of these referencing cli.github.com or a repo named gh-cli, this is the same issue โ€” go straight to the fix for your package manager below.

Who's affected (check this first)

You only need to do anything if all of these are true:

  • You're on Linux (this does not affect Windows, macOS, Homebrew, Conda, direct .deb/.rpm downloads, or building from source)
  • You installed gh via the official apt or rpm repository
  • You haven't re-run the official install steps since April 8, 2026

Quick check on Debian/Ubuntu โ€” look at the modification time on the keyring file:

1ls -l /etc/apt/keyrings/githubcli-archive-keyring.gpg /usr/share/keyrings/githubcli-archive-keyring.gpg 2>/dev/null

If that file predates April 2026, or apt update is already throwing the errors above, you need the fix.

The fix

Debian / Ubuntu (apt)

Re-download the current keyring โ€” this pulls both keys and immediately restores trust:

1sudo mkdir -p -m 755 /etc/apt/keyrings
2sudo curl -fsSL -o /etc/apt/keyrings/githubcli-archive-keyring.gpg https://cli.github.com/packages/githubcli-archive-keyring.gpg
3sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg
4sudo apt update
5sudo apt install gh

If your system doesn't have curl, wget works identically:

1sudo wget -qO /etc/apt/keyrings/githubcli-archive-keyring.gpg https://cli.github.com/packages/githubcli-archive-keyring.gpg

Some older installs still keep the keyring at /usr/share/keyrings/githubcli-archive-keyring.gpg instead of /etc/apt/keyrings/ โ€” check your /etc/apt/sources.list.d/github-cli.list to see which path your signed-by line actually points at, and overwrite that file specifically.

Fedora 41+ (dnf5)

1sudo dnf config-manager addrepo --overwrite --from-repofile=https://cli.github.com/packages/rpm/gh-cli.repo
2sudo dnf update gh

CentOS, RHEL, Fedora 40 or earlier (dnf4)

1sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
2sudo dnf update gh

Amazon Linux 2 (yum)

1sudo yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
2sudo yum update gh

openSUSE / SUSE (zypper)

1sudo zypper removerepo gh-cli
2sudo zypper addrepo https://cli.github.com/packages/rpm/gh-cli.repo
3sudo zypper update gh

The RPM-based commands all work the same way: re-adding the repo definition pulls the current signed repo file, which references the new key, resolving the NO_PUBKEY/expired-certificate errors on the next update.

Verifying the fix worked

After running the appropriate commands above, confirm two things separately โ€” don't just trust that the command exited 0:

1gh --version
2sudo apt update   # or dnf/yum/zypper equivalent โ€” should complete with no signature warnings

If apt update is still clean and gh --version reports the latest release, you're done. On Debian/Ubuntu you can also confirm the new key fingerprint is present:

1gpg --no-default-keyring --keyring /etc/apt/keyrings/githubcli-archive-keyring.gpg --list-keys

Look for a key fingerprint ending in ...462313325 (the new key) alongside or instead of the old ...5716059 fingerprint.

Best practices

  • Don't pin or vendor the keyring file in golden images, Docker base images, or infra-as-code without a refresh mechanism โ€” this exact failure mode (a baked-in keyring going stale) is why this bit so many systems at once. If you bake gh into a container image, re-pull the keyring on every image rebuild rather than caching it indefinitely.
  • Automate the check. If you manage fleets of Linux hosts with gh installed, add a periodic check (cron, Ansible fact, or a CI job) that runs apt update/dnf check-update and alerts on signature errors โ€” you don't want to find out about the next rotation from a broken deploy pipeline.
  • Prefer the official repo over manual .deb downloads for anything long-lived โ€” repo-based installs get key rotations automatically once you're current, whereas a one-off downloaded .deb has no ongoing verification story at all.

Common mistakes to avoid

  • Deleting the keyring file instead of replacing it. Removing githubcli-archive-keyring.gpg without adding a new one just changes the error to "public key not available" โ€” you still need to fetch the current file.
  • Editing sources.list by hand to disable signature checking ([trusted=yes] or --nogpgcheck) as a "fix." This silences the error but disables package integrity verification entirely โ€” never do this as a permanent workaround, only ever as a five-minute diagnostic step you immediately revert.
  • Assuming a gh reinstall alone fixes it. If your gh binary itself came from a .deb you downloaded once, reinstalling it doesn't touch the repository's keyring โ€” the apt update failures on the repo entry persist until the keyring file itself is refreshed.

Troubleshooting

apt update still fails after refreshing the keyring. Double check the signed-by path in /etc/apt/sources.list.d/github-cli.list actually matches the file you just wrote. A mismatch (e.g. the source list points at /usr/share/keyrings/... but you refreshed /etc/apt/keyrings/...) leaves the old, now-unverifiable reference in place.

dnf update gh reports "repository not found" after re-adding. Run sudo dnf repolist to confirm gh-cli is enabled, and check /etc/yum.repos.d/gh-cli.repo was actually overwritten with a recent timestamp.

Corporate proxy or mirror in front of cli.github.com. If your organization mirrors GitHub's package repos internally, the mirror needs to sync the updated keyring/repo files too โ€” this fix only works directly against cli.github.com.

FAQ

Does this affect GitHub Actions runners? Only self-hosted Linux runners where gh was installed via apt/dnf/yum before April 2026 and never updated. GitHub-hosted runner images are maintained by GitHub and already carry the current key.

Do I need to reinstall gh itself, or just refresh the keyring? Usually just the keyring/repo refresh โ€” gh itself isn't broken, only the trust chain used to verify its packages. Running the update command afterward will pick up the latest gh release as a side effect, which is good practice anyway.

Will this happen again with future key rotations? Yes โ€” GitHub rotates this key periodically (a similar rotation happened in 2024), and each time, systems that installed once and never updated their keyring are affected. There's no way to make a repo-based install permanently immune; the mitigation is keeping systems current, not a one-time fix.

I'm on Homebrew/macOS/Windows โ€” do I need to do anything? No. This issue is specific to the Linux apt/rpm package repositories; Homebrew, the Windows installer, and direct binary downloads use different distribution and verification mechanisms unaffected by this rotation.

What if I can't identify which package manager broke? Run command -v apt dnf yum zypper to see which are present, then check cat /etc/apt/sources.list.d/*.list 2>/dev/null or cat /etc/yum.repos.d/*.repo 2>/dev/null for a cli.github.com or gh-cli entry โ€” that tells you which fix above applies.

Key takeaways

SituationAction
Installed/updated gh via official repo after April 8, 2026No action needed
apt update shows EXPKEYSIG/NO_PUBKEY for cli.github.comRe-download the keyring file (see apt fix above)
dnf/yum update gh shows expired-certificate or unknown-key errorsRe-add the repo via config-manager/yum-config-manager
Managing a fleet with gh baked into imagesRefresh the keyring in the image build, don't cache indefinitely
Using Homebrew, Windows, macOS, or direct .deb/.rpm downloadsNot affected

Further Reading