This error occurs when apt tries to add a GPG key for a repository but the gnupg package is not installed on the system. This commonly happens in minimal Docker images or fresh Linux installations when running apt-key commands.
When you attempt to add a GPG key to apt using the `apt-key add` command, apt requires the gnupg package to verify and process the key. If gnupg (or gnupg2/gnupg1) is not installed, apt will fail with this error. The error specifically appears when: - Running `curl ... | apt-key add -` to add repository keys - Using `apt-key adv` commands - Adding PPA (Personal Package Archive) keys - Verifying package signatures during installation This is especially common in minimal Docker images like `ubuntu:latest` or `debian:slim` which don't include gnupg in the base image to reduce size.
Before installing packages, update the apt package cache to ensure you have the latest package information.
apt-get updateThis is required before any apt-get install commands, especially in fresh or minimal images.
Install the gnupg package which provides the GPG functionality needed for key management.
apt-get install -y gnupgOr if you need gnupg2 specifically:
apt-get install -y gnupg2The -y flag automatically answers "yes" to confirmation prompts, useful for automated environments like Docker builds.
After installing gnupg, you can now add repository keys. Use one of these methods:
Method 1: Using apt-key with curl
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -Method 2: Direct key file download and import
curl -fsSL https://apt.example.com/key.gpg -o /tmp/key.gpg
apt-key add /tmp/key.gpg
rm /tmp/key.gpgMethod 3: Using wget instead of curl
wget -qO- https://apt.example.com/key.gpg | apt-key add -The flags used:
- -f: Fail on server errors
- -s: Silent mode (no progress bar)
- -S: Show errors even in silent mode
- -L: Follow redirects
- -q: Quiet output
In Dockerfiles, it's best practice to combine apt-get update, package installation, and key addition in a single RUN layer to minimize image size and avoid caching issues.
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y gnupg && \
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \
apt-get install -y llvm
# Continue with other Dockerfile instructionsWhy combine into one RUN?
- Each RUN instruction creates a new layer in the Docker image
- Combining reduces the number of layers and final image size
- Ensures apt-get update runs immediately before installation (better cache handling)
Confirm that the GPG key has been added to apt's keyring.
# List all trusted keys
apt-key list
# Or search for a specific key by name
apt-key list | grep -i "llvm"You should see the key in the output if it was added successfully.
Note: apt-key is deprecated in modern Debian/Ubuntu versions. See advanced notes below for modern alternatives.
With the key installed, you can now add the repository and install packages.
# Add the repository (if using apt-add-repository)
apt-add-repository "deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy main"
# Or add the source directly to sources.list.d/
echo "deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy main" | \
tee /etc/apt/sources.list.d/llvm.list > /dev/null
# Update again to fetch packages from the new repository
apt-get update
# Install packages from the new repository
apt-get install -y llvmFor PPAs:
# Install software-properties-common for ppa handling
apt-get install -y software-properties-common
# Add PPA (automatically handles key management)
add-apt-repository ppa:user/ppa-name
# Update and install
apt-get update
apt-get install -y package-name### Modern Alternative: Signed-by Method (Debian 12+, Ubuntu 22.04+)
The apt-key method is deprecated. Modern versions of Debian and Ubuntu support the signed-by option, which is more secure and doesn't require gnupg for key management.
# Download the key directly to /etc/apt/keyrings/
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | \
gpg --dearmor -o /etc/apt/keyrings/llvm-snapshot-archive-keyring.gpg
# Add the repository with signed-by pointing to the key
echo "deb [signed-by=/etc/apt/keyrings/llvm-snapshot-archive-keyring.gpg] https://apt.llvm.org/jammy/ llvm-toolchain-jammy main" | \
tee /etc/apt/sources.list.d/llvm.list > /dev/null
# Update without needing apt-key
apt-get updateAdvantages:
- Doesn't require installing gnupg
- More secure than global apt-key rings
- Repository-specific keys don't affect other repositories
- Works better in minimal Docker images
Dockerfile example:
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y curl && \
mkdir -p /etc/apt/keyrings && \
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor -o /etc/apt/keyrings/llvm-snapshot-archive-keyring.gpg && \
echo "deb [signed-by=/etc/apt/keyrings/llvm-snapshot-archive-keyring.gpg] https://apt.llvm.org/jammy/ llvm-toolchain-jammy main" | \
tee /etc/apt/sources.list.d/llvm.list > /dev/null && \
apt-get update && \
apt-get install -y llvmThis method is preferred for new projects and Docker images.
### Using software-properties-common for PPA Management
For PPAs (Personal Package Archives), using add-apt-repository is often simpler:
FROM ubuntu:22.04
RUN apt-get update && \
apt-get install -y software-properties-common && \
add-apt-repository ppa:deadsnakes/ppa && \
apt-get update && \
apt-get install -y python3.11The add-apt-repository command automatically handles key management and doesn't require manual gnupg installation.
### Minimal Docker Images and Package Size
If minimizing Docker image size is critical, avoid installing gnupg and use the signed-by method instead:
With gnupg (larger):
RUN apt-get update && apt-get install -y gnupg # ~4-5 MB addedWith signed-by (smaller):
RUN apt-get update && apt-get install -y curl # ~1-2 MB added (curl likely needed anyway)### Troubleshooting apt-key Issues in Minimal Environments
If "command not found: apt-key":
Install apt-utils:
apt-get update && apt-get install -y apt-utilsIf gpg hangs or has permission errors:
- Ensure /dev/null is available (required for GPG operations)
- In Docker, may need to mount /dev properly
- Check disk space - GPG can fail silently on full disks
If key verification still fails after installation:
# Force insecure installation (NOT recommended for production)
apt -o Acquire::AllowInsecureRepositories=true -o Acquire::AllowDowngradeToInsecureRepositories=true updateThis is a workaround only and shouldn't be used unless the repository key is genuinely unavailable.
### Full Docker Example: Multi-stage Build with Repository Keys
FROM ubuntu:22.04 as builder
# Single RUN layer for efficiency
RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl \
ca-certificates && \
mkdir -p /etc/apt/keyrings && \
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | \
gpg --dearmor -o /etc/apt/keyrings/llvm-snapshot-archive-keyring.gpg && \
echo "deb [signed-by=/etc/apt/keyrings/llvm-snapshot-archive-keyring.gpg] https://apt.llvm.org/jammy/ llvm-toolchain-jammy main" | \
tee /etc/apt/sources.list.d/llvm.list && \
apt-get update && \
apt-get install -y --no-install-recommends llvm-14 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
FROM ubuntu:22.04
COPY --from=builder /usr/lib/llvm-14 /usr/lib/llvm-14
COPY --from=builder /usr/bin/llvm* /usr/bin/The --no-install-recommends flag reduces package size by skipping optional dependencies.
E: Could not connect to proxy server
Could not connect to proxy server
E: Package 'package:i386' has no installation candidate
How to fix "Package package:i386 has no installation candidate" in apt
E: The value 'value' is invalid for APT::Default-Release
How to fix invalid APT::Default-Release value in APT
dpkg: error: unable to create new file 'path': Permission denied
How to fix dpkg permission denied errors in APT
subprocess installed post-removal script returned error exit status 1
How to fix "subprocess installed post-removal script returned error exit status 1" in APT