← all posts

Troubleshooting apt NO_PUBKEY Errors

May 6, 2024
Troubleshooting apt NO_PUBKEY Errors

When apt update fails with NO_PUBKEY, the problem is usually not networking or IAM permissions. It means apt cannot verify the repository signature with a trusted public key.

This commonly happens when a third-party repository rotates its signing key.

Symptom

The error looks like:

W: GPG error: https://example.repo/deb ... NO_PUBKEY <KEY_ID>
E: The repository ... is not signed.

apt refuses to trust package metadata because signature verification failed.

Why apt Verifies Signatures

Package managers download code that will run as root. apt needs evidence that package metadata came from the repository owner and was not modified in transit.

The repository signs metadata with a private key. The client verifies that signature with a trusted public key.

Why Keys Change

Repository owners may rotate signing keys because:

  1. A key may be old.
  2. A stronger algorithm is preferred.
  3. A private key might be suspected of exposure.
  4. Security policy requires rotation.

apt does not automatically trust a new third-party key. That is a feature, not a bug. Automatically trusting whatever key a remote endpoint provides would weaken the entire trust model.

Find The Source File

First locate the repository configuration:

grep -r repo-name /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null

Do not guess the file name. Inspect the current state.

Install The New Keyring

Modern Ubuntu systems should use a dedicated keyring:

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://example.repo/public.key \
  | sudo gpg --dearmor --yes -o /etc/apt/keyrings/example.gpg

gpg --dearmor converts an ASCII public key into a binary keyring format apt can use.

Bind The Repository To That Key

Use signed-by:

echo "deb [signed-by=/etc/apt/keyrings/example.gpg] https://example.repo/deb noble main" \
  | sudo tee /etc/apt/sources.list.d/example.list

Do not use sudo echo ... > file. The redirection is performed by your shell, not by sudo. Use sudo tee.

Old vs New Trust Model

The old model placed keys in a global trusted pool. Any trusted key could potentially validate any repository. The newer signed-by model binds one key to one repository, reducing blast radius.

Prevention

For fleets, manage repository keys through Ansible, Systems Manager, AMI baking, or cloud-init. Make the key and source file idempotent. For critical tooling, prefer repositories that ship a keyring package or use binary/container distribution when appropriate.

The main lesson: NO_PUBKEY is a trust-chain problem. Fix the trust chain deliberately.

;