This GPG warning appears when verifying signed Git commits or tags when the signing key is not in your web of trust. The signature is cryptographically valid, but GPG cannot confirm who owns the key. Fix this by signing the key or setting its trust level.
The "gpg: WARNING: This key is not certified with a trusted signature!" warning indicates that while GPG can verify the signature is cryptographically valid (the data hasn't been tampered with), it cannot confirm that the key actually belongs to the person it claims to represent. This is a fundamental concept in GPG's web of trust model. Just having someone's public key in your keyring doesn't mean you trust their identity. GPG requires a "trust path" - either you've personally verified and signed their key, or someone whose key you've signed has signed their key. When verifying Git commits or tags, Git uses GPG to check signatures. If the key isn't in your web of trust, GPG shows this warning. Importantly, this is a WARNING, not an ERROR. The signature verification still succeeds (exit code 0), and the commit/tag is marked with "U" (good signature, unknown validity) rather than "G" (good signature, valid key). This warning is expected behavior when: - You've imported someone's public key but haven't signed it - You're verifying commits from a colleague whose key you haven't formally verified - You're checking signatures from open source maintainers you've never met - You cloned a repository with signed commits but don't have the signers' keys in your trust chain
First, confirm that this is just a trust warning and not an actual signature problem:
Check commit signature:
# Verify a specific commit
git verify-commit HEAD
# Or check signatures in log
git log --show-signature -1Check tag signature:
git verify-tag v1.0.0Understanding the output:
- "Good signature" = cryptographically valid (file not tampered)
- WARNING about trust = identity not verified in your web of trust
- Exit code 0 = verification succeeded
Check GPG's assessment:
# Get the key ID from the signature output, then:
gpg --list-keys <KEY_ID>
# Check trust level
gpg --list-keys --with-colons <KEY_ID> | grep -E "^(pub|uid)"The warning is informational - your commit is legitimately signed, you just haven't verified the signer's identity.
If you don't have the key, import it first:
From a keyserver:
# Search for key by email
gpg --keyserver keyserver.ubuntu.com --search-keys [email protected]
# Or import by key ID
gpg --keyserver keyserver.ubuntu.com --recv-keys <KEY_ID>From GitHub/GitLab:
# GitHub: https://github.com/<username>.gpg
curl https://github.com/torvalds.gpg | gpg --import
# GitLab: https://gitlab.com/<username>.gpg
curl https://gitlab.com/username.gpg | gpg --importVerify the fingerprint:
Before trusting a key, verify its fingerprint through a trusted channel (in person, video call, trusted website):
# Show full fingerprint
gpg --fingerprint <KEY_ID>
# Compare with fingerprint published on:
# - User's personal website (over HTTPS)
# - Official project documentation
# - In-person verificationIf you've verified the key belongs to who it claims (e.g., a coworker you know), sign it:
Interactive signing:
gpg --edit-key <KEY_ID>
# At the gpg> prompt:
gpg> sign
# Confirm with 'y'
gpg> saveLocal signing (doesn't export to keyservers):
gpg --edit-key <KEY_ID>
gpg> lsign
gpg> saveNon-interactive local signing:
gpg --quick-lsign-key <KEY_ID>The difference:
- sign = certification can be exported and shared
- lsign = certification stays on your machine only (safer for casual trust)
After signing, the warning will disappear for commits signed by this key.
If you trust a key but don't want to sign it (perhaps you can't verify identity but trust the source):
Interactive trust setting:
gpg --edit-key <KEY_ID>
# At the gpg> prompt:
gpg> trust
# Select trust level:
# 1 = I don't know or won't say
# 2 = I do NOT trust
# 3 = I trust marginally
# 4 = I trust fully
# 5 = I trust ultimately (use only for your own keys)
# Choose 4 for most cases
gpg> quitNon-interactive trust setting:
# Get the fingerprint
FINGERPRINT=$(gpg --fingerprint <KEY_ID> | grep -A1 "pub" | tail -1 | tr -d ' ')
# Set trust level (format: fingerprint:trust_level:)
echo "${FINGERPRINT}:4:" | gpg --import-ownertrustAlternative: Add to gpg.conf:
# Add to ~/.gnupg/gpg.conf
echo "trusted-key <LONG_KEY_ID>" >> ~/.gnupg/gpg.confThis marks the key as ultimately trusted (equivalent to trust level 5).
GPG supports different trust models. For some workflows, the default 'pgp' model may be overly strict:
Direct trust model (trust keys you've imported):
# Per-command
gpg --trust-model direct --verify-commit HEAD
# Or set globally in ~/.gnupg/gpg.conf
echo "trust-model direct" >> ~/.gnupg/gpg.confAlways trust model (for testing/CI only):
# Trusts any imported key - NOT recommended for production
gpg --trust-model always --verify signature.sig fileGit-specific verification options:
# Require valid signature but ignore trust
git config --global gpg.minTrustLevel never
# Require at least marginal trust
git config --global gpg.minTrustLevel marginal
# Require full trust
git config --global gpg.minTrustLevel fullyFor CI pipelines:
The warning goes to stderr, but gpg returns exit code 0 for valid signatures. Your CI should check exit codes, not parse warning messages.
If you understand the warning and want to suppress it:
Option 1: Use trust-model in gpg.conf:
# ~/.gnupg/gpg.conf
trust-model directOption 2: Mark the specific key as trusted:
# Add to ~/.gnupg/gpg.conf
trusted-key <LONG_KEY_ID>Option 3: Redirect stderr (scripting):
# The warning goes to stderr, signature result to stdout
git verify-commit HEAD 2>/dev/null
echo $? # 0 = valid signatureOption 4: For merge verification:
Git's --verify-signatures during merge looks for "G" (valid+trusted) status. To accept "U" (valid+untrusted):
# Git 2.19+
git config merge.verifySignatures true
git config gpg.minTrustLevel neverCaution: Suppressing this warning removes a security check. Only do this if you have another way to verify signer identity.
Understanding GPG Trust Levels:
GPG uses a web of trust model with these owner trust levels:
- Unknown (1): You don't know how carefully this person verifies keys
- Never (2): You don't trust this person to verify keys
- Marginal (3): You somewhat trust their key verification
- Full (4): You fully trust their key verification
- Ultimate (5): This is YOUR key (reserved for your own keys)
Trust is about identity verification, not data integrity. A "U" signature means the data is intact; you just can't prove who signed it.
Git Signature Status Codes:
When verifying signatures, Git reports:
- G: Good signature, valid key (trusted)
- U: Good signature, unknown validity (not in trust chain)
- B: Bad signature (data corrupted or wrong key)
- X: Good signature, expired key
- Y: Good signature, expired certification
- R: Good signature, revoked key
- E: Cannot check (missing key)
- N: No signature
The "U" status is what triggers this warning - cryptographically valid but not in your web of trust.
Why the Web of Trust Matters:
Anyone can create a GPG key claiming to be "Linus Torvalds." The web of trust ensures:
1. You only trust keys you've personally verified
2. Or keys verified by people you trust
3. This chain prevents impersonation attacks
Without the web of trust, an attacker could sign malicious commits with a fake key.
Verification Best Practices:
For open source projects:
1. Check if the key fingerprint is on the project's official website
2. Look for the key in official documentation
3. Verify the fingerprint matches what's published over HTTPS
For colleagues:
1. Verify fingerprints in person or via video call
2. Use your organization's key signing procedures
3. Consider using lsign for local-only trust
CI/CD Considerations:
In automated pipelines, you typically:
1. Import maintainers' keys non-interactively
2. Mark them as trusted using --import-ownertrust
3. Check exit codes rather than parsing output
Example CI setup:
# Import and trust a key
gpg --import maintainer.key
FINGERPRINT=$(gpg --fingerprint [email protected] | grep -A1 "pub" | tail -1 | tr -d ' ')
echo "${FINGERPRINT}:4:" | gpg --import-ownertrust
# Now verification won't warn
git verify-commit HEADMulti-Device Key Management:
When using the same GPG key on multiple machines:
1. Export your key: gpg --export-secret-keys -a > private.key
2. Import on new machine: gpg --import private.key
3. Set ultimate trust: gpg --edit-key <KEY_ID> then trust then 5
Your own key needs ultimate trust for the web of trust to work properly from that machine.
Keyserver Considerations:
Public keyservers allow anyone to upload keys, so never trust a key just because it's on a keyserver. Always verify fingerprints through independent channels. Some projects use dedicated key distribution:
- Linux kernel: https://www.kernel.org/signature.html
- Git: https://github.com/git/git/blob/master/Documentation/RelNotes/*.txt (signed tags)
warning: BOM detected in file, this may cause issues
UTF-8 Byte Order Mark (BOM) detected in file
fatal: Server does not support --shallow-exclude
Server does not support --shallow-exclude
warning: filtering out blobs larger than limit
Git partial clone filtering large blobs warning
fatal: Server does not support --shallow-since
Server does not support --shallow-since in Git
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server