getsops/sops · critical
could not decrypt data key with PGP key: %w
Error message
could not decrypt data key with PGP key: %w
What it means
This is the aggregate error returned by DecryptContext after both the go-crypto OpenPGP attempt and the gpg-binary fallback failed to decrypt the data key. It wraps the collected list of both errors. Seeing it means none of the available PGP mechanisms could recover the sops data key for this master key, so the file cannot be decrypted with this recipient.
Source
Thrown at pgp/keysource.go:415
if !key.disableOpenPGP {
dataKey, openpgpErr := key.decryptWithOpenPGP()
if openpgpErr == nil {
log.WithField("fingerprint", key.Fingerprint).Info("Decryption succeeded")
return dataKey, nil
}
errs = append(errs, fmt.Errorf("github.com/ProtonMail/go-crypto/openpgp error: %w", openpgpErr))
}
dataKey, binaryErr := key.decryptWithGnuPG(ctx)
if binaryErr == nil {
log.WithField("fingerprint", key.Fingerprint).Info("Decryption succeeded")
return dataKey, nil
}
errs = append(errs, fmt.Errorf("GnuPG binary error: %w", binaryErr))
log.WithField("fingerprint", key.Fingerprint).Info("Decryption failed")
return nil, fmt.Errorf("could not decrypt data key with PGP key: %w", errs)
}
// decryptWithOpenPGP attempts to obtain the data key from the EncryptedKey
// using OpenPGP and returns the result.
//
// Note: the current development of OpenPGP vs GnuPG has moved in separate
// directions. This means that e.g. GnuPG >=2.1 works with a .kbx format which
// can not be read by OpenPGP. Given the further assumptions around the
// placement of the files, and the generic fallback Decrypt uses, this raises
// the question of how widely utilized this method still is.
func (key *MasterKey) decryptWithOpenPGP() ([]byte, error) {
ring, err := key.getSecRing()
if err != nil {
return nil, fmt.Errorf("could not load secring: %s", err)
}
block, err := armor.Decode(strings.NewReader(key.EncryptedKey))
if err != nil {
return nil, fmt.Errorf("armor decoding failed: %s", err)View on GitHub (pinned to 13442bb981)
Solutions
- Read both wrapped causes; typically import the private key for the fingerprint
- Verify gpg --list-secret-keys shows the fingerprint; import with gpg --import if not
- Ensure the environment can supply the passphrase (GPG_TTY, gpg-agent, loopback pinentry in CI)
- If the file was encrypted to a fingerprint you cannot access, obtain the key from the owner or restore it from backup, then re-encrypt: sops updatekeys file.yaml
Example fix
// before sops -d file.yaml # could not decrypt data key with PGP key // after gpg --import backup-secret.asc && gpg --list-secret-keys <fingerprint> && sops -d file.yaml
Defensive patterns
Strategy: try-catch
Validate before calling
out, err := exec.Command("gpg", "--list-secret-keys", fingerprint).CombinedOutput()
if err != nil || !strings.Contains(string(out), fingerprint) {
return fmt.Errorf("cannot decrypt: no secret key for %s; import it first", fingerprint)
} Try / catch
dk, err := key.DecryptContext(ctx)
if err != nil {
var errs []error
if errors.As(err, &errs) {
for _, e := range errs { log.Errorf("decrypt: %v", e) }
}
return fmt.Errorf("PGP master key %s cannot decrypt file (missing/unlockable private key): %w", key.Fingerprint, err)
} Prevention
- Maintain encrypted backups of the private keys for every fingerprint in .sops.yaml
- Bootstrap machines/CI with a documented key-import step before sops -d
- If keys rotated, run sops updatekeys to re-encrypt files to current recipients
- Test decryption non-interactively (echo test | gpg -se -r fp | gpg -d) in setup validation
When it happens
Trigger: Calling DecryptContext (or sops -d) when the private key for the fingerprint is unavailable/unlockable in both mechanisms: not imported, wrong GNUPGHOME, passphrase unavailable, or the EncryptedKey blob is corrupt/rotated to a key you lack.
Common situations: New laptop or CI runner without the secret key; team member removed from key access; file encrypted to an old/rotated fingerprint; gpg-agent passphrase prompts impossible in non-interactive shells.
Related errors
- could not encrypt data key with PGP key: %w
- github.com/ProtonMail/go-crypto/openpgp error: %w
- Unknown datatype: %s
- incorrect passphrase
- failed to decrypt identity file: %v
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/0a23158df4706a06.
Report an issue: GitHub.