This error occurs when GPG creates a new keybox file but cannot use it, typically due to the keyboxd daemon configuration in newer GPG versions (2.4.1+), corrupted GPG home directory, or permission issues. The fix involves either disabling keyboxd mode or reinitializing the GPG directory.
The "gpg: keybox created but not usable" error indicates that GPG successfully created the pubring.kbx keybox file but cannot read from or write to it properly. This prevents Git from signing commits or tags because GPG cannot access your cryptographic keys. The keybox (pubring.kbx) is a database file that stores your public GPG keys. In GnuPG 2.1 and later, this replaced the older pubring.gpg format for better performance. However, GnuPG 2.4.1 introduced a new "keyboxd" daemon mode that changes how keys are stored and accessed. When this error appears during Git operations, it typically means: - **GPG 2.4.1+ is using keyboxd by default**, but the daemon isn't running or properly configured - **The keybox file is corrupted** or was created with incompatible settings - **Permission issues** prevent GPG from accessing or modifying the keybox - **The GPG home directory structure is incomplete** or damaged - **A lock file is blocking access** to the keybox This error often surprises developers after a GPG upgrade or when setting up a new machine, as the default behavior changed significantly in recent versions.
First, determine which GPG version you have and whether keyboxd is in use:
Check GPG version:
gpg --versionIf version is 2.4.1 or higher, keyboxd is likely enabled by default on fresh installations.
Check for keyboxd configuration:
# Look for use-keyboxd in common.conf
cat ~/.gnupg/common.conf 2>/dev/null
# Check if keyboxd process is running
pgrep -a keyboxdTest GPG key listing:
gpg --list-keysIf this produces the error, proceed with the fixes below.
For most users, disabling keyboxd and reverting to the traditional pubring.kbx format resolves the issue:
Remove or comment out use-keyboxd:
# Check if common.conf exists and contains use-keyboxd
grep -r "use-keyboxd" ~/.gnupg/
# If found, remove or comment it out
sed -i 's/^use-keyboxd/#use-keyboxd/' ~/.gnupg/common.confOr create/edit common.conf to explicitly disable:
# Ensure the directory exists
mkdir -p ~/.gnupg
chmod 700 ~/.gnupg
# Remove the use-keyboxd line if it exists
# Or create an empty common.conf
echo "# keyboxd disabled for compatibility" > ~/.gnupg/common.confRestart GPG agent:
gpgconf --kill allNow try listing keys again:
gpg --list-keysIf the keybox is corrupted beyond repair, reinitialize the GPG directory:
Backup existing keys first (if possible):
# Try to export keys before resetting
gpg --export --armor > ~/gpg-public-keys-backup.asc
gpg --export-secret-keys --armor > ~/gpg-secret-keys-backup.asc
gpg --export-ownertrust > ~/gpg-ownertrust-backup.txtMove the old directory and create fresh:
# Stop all GPG processes
gpgconf --kill all
# Backup and remove old directory
mv ~/.gnupg ~/.gnupg-backup-$(date +%Y%m%d)
# Create new directory with correct permissions
mkdir -p ~/.gnupg
chmod 700 ~/.gnupg
# Initialize fresh keybox
gpg --list-keysRestore keys if you had backups:
gpg --import ~/gpg-public-keys-backup.asc
gpg --import ~/gpg-secret-keys-backup.asc
gpg --import-ownertrust ~/gpg-ownertrust-backup.txtGPG requires strict permissions on its home directory and files:
Set correct permissions on the GPG directory:
# Directory must be 700 (rwx------)
chmod 700 ~/.gnupg
# All files should be 600 (rw-------)
chmod 600 ~/.gnupg/*
# Subdirectories need 700
find ~/.gnupg -type d -exec chmod 700 {} \;
# Files need 600
find ~/.gnupg -type f -exec chmod 600 {} \;Check ownership:
ls -la ~/.gnupg
# If ownership is wrong (e.g., root), fix it
sudo chown -R $(whoami):$(whoami) ~/.gnupgRemove stale lock files:
rm -f ~/.gnupg/*.lock
rm -f ~/.gnupg/public-keys.d/*.lockEnsure Git is using the correct GPG binary and your signing key is properly configured:
Set GPG program for Git:
# Use gpg2 if available (some systems have both gpg and gpg2)
which gpg2 && git config --global gpg.program gpg2
# Or explicitly use gpg
git config --global gpg.program gpgVerify your signing key:
# List secret keys to find your key ID
gpg --list-secret-keys --keyid-format=long
# Example output shows key ID after "sec rsa4096/"
# sec rsa4096/ABC123DEF456GHI7 2024-01-01 [SC]Configure Git with your key:
git config --global user.signingkey YOUR_KEY_ID
git config --global commit.gpgsign trueSet GPG_TTY for terminal access:
# Add to ~/.bashrc or ~/.zshrc
export GPG_TTY=$(tty)Verify that GPG signing now works with Git:
Test GPG directly:
echo "test" | gpg --clearsignThis should prompt for your passphrase and output a signed message. If this fails, the issue is with GPG itself, not Git.
Test Git signing:
# Create a test commit with signing
git commit --allow-empty -S -m "Test signed commit"
# Verify the signature
git log --show-signature -1Debug if still failing:
# Enable Git tracing
GIT_TRACE=1 git commit --allow-empty -S -m "Debug test"If you see "gpg failed to sign the data", check the GPG agent:
gpgconf --kill gpg-agent
gpg-agent --daemonUnderstanding the Keyboxd Architecture (GnuPG 2.4.1+):
GnuPG 2.4.1 introduced keyboxd, a new daemon for managing keyrings. When enabled via use-keyboxd in ~/.gnupg/common.conf, keys are no longer stored in pubring.kbx directly. Instead, they're managed by the keyboxd process in its own database format.
This change caused widespread compatibility issues because:
1. Many tools assume pubring.kbx exists and is readable
2. Container environments may not have keyboxd running
3. The daemon requires proper socket communication
The Keybox File Format:
GnuPG 2.1+ uses the keybox format (.kbx) instead of the older OpenPGP keyring format (.gpg). The keybox format:
- Stores keys in a SQLite-like binary format
- Provides faster key lookups for large keyrings
- Combines public and private key references
- Requires the keybox library to read/write
Diagnosing Corruption:
# Check if keybox is valid
kbxutil ~/.gnupg/pubring.kbx
# Examine keybox contents (if readable)
gpg --list-keys --keyring ~/.gnupg/pubring.kbx
# Check for database inconsistencies
gpg --check-trustdbEnvironment-Specific Issues:
Docker/Containers:
- Keyboxd may not run properly in containers
- Volume mounts can cause permission issues
- Add to Dockerfile: RUN mkdir -p ~/.gnupg && chmod 700 ~/.gnupg
WSL (Windows Subsystem for Linux):
- File permissions may not be enforced correctly on Windows filesystems
- Store .gnupg on the Linux filesystem, not in /mnt/c/
- Consider using the Windows GPG with: git config --global gpg.program "/mnt/c/Program Files (x86)/GnuPG/bin/gpg.exe"
macOS:
- Homebrew GPG may conflict with system GPG
- Pinentry configuration is often needed:
brew install pinentry-mac
echo "pinentry-program $(brew --prefix)/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agentCI/CD Environments:
For GitHub Actions, GitLab CI, etc.:
# Import key without keyboxd
- name: Import GPG key
run: |
echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --import
echo "use-agent" >> ~/.gnupg/gpg.conf
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agentConverting Between Keyring Formats:
If you need to convert from the old format:
# Backup ownertrust
gpg --export-ownertrust > otrust.txt
# Export all keys
gpg --export --armor > public-keys.asc
gpg --export-secret-keys --armor > secret-keys.asc
# Reset and reimport
rm -rf ~/.gnupg
mkdir -p ~/.gnupg && chmod 700 ~/.gnupg
gpg --import public-keys.asc
gpg --import secret-keys.asc
gpg --import-ownertrust otrust.txtSecurity Note:
When troubleshooting GPG issues:
- Never share your secret key backup files
- Delete backup files after importing: shred -u secret-keys.asc
- Be cautious with --batch and --pinentry-mode loopback as they bypass security prompts
- Keep ~/.gnupg permissions strict (700 for directories, 600 for files)
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git