getsops/sops · error
github.com/ProtonMail/go-crypto/openpgp error: %w
Error message
github.com/ProtonMail/go-crypto/openpgp error: %w
What it means
EncryptContext tries key.encryptWithOpenPGP (github.com/ProtonMail/go-crypto/openpgp) first; if it fails and OpenPGP is not disabled, the error is appended as 'github.com/ProtonMail/go-crypto/openpgp error: %w'. This is one of two attempts collected before the aggregate failure; it means the pure-Go OpenPGP path could not encrypt the data key to the key's fingerprint (missing key in keyring, unreadable pubring, malformed key, etc.).
Source
Thrown at pgp/keysource.go:284
// fingerprint as the MasterKey.
//
// Consider using EncryptContext instead.
func (key *MasterKey) Encrypt(dataKey []byte) error {
return key.EncryptContext(context.Background(), dataKey)
}
// EncryptContext encrypts the data key with the PGP key with the same
// fingerprint as the MasterKey.
func (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {
var errs errSet
if !key.disableOpenPGP {
openpgpErr := key.encryptWithOpenPGP(dataKey)
if openpgpErr == nil {
log.WithField("fingerprint", key.Fingerprint).Info("Encryption succeeded")
return nil
}
errs = append(errs, fmt.Errorf("github.com/ProtonMail/go-crypto/openpgp error: %w", openpgpErr))
}
binaryErr := key.encryptWithGnuPG(ctx, dataKey)
if binaryErr == nil {
log.WithField("fingerprint", key.Fingerprint).Info("Encryption succeeded")
return nil
}
errs = append(errs, fmt.Errorf("GnuPG binary error: %w", binaryErr))
log.WithField("fingerprint", key.Fingerprint).Info("Encryption failed")
return fmt.Errorf("could not encrypt data key with PGP key: %w", errs)
}
// encryptWithOpenPGP attempts to encrypt the data key using OpenPGP with the
// PGP key that belongs to Fingerprint. It sets EncryptedDataKey, or returns
// an error.
func (key *MasterKey) encryptWithOpenPGP(dataKey []byte) error {
entity, err := key.retrievePubKey()View on GitHub (pinned to 13442bb981)
Solutions
- Import the recipient public key: gpg --import <pubkey-file> (into the GNUPGHOME sops uses)
- Export to a legacy-format keyring readable by go-crypto, or set SOPS_GPG_EXEC and rely on the gpg-binary fallback
- Verify the fingerprint matches an existing key: gpg --list-keys <fingerprint>
- If you intend to use only the gpg binary, ensure the binary path is valid so the fallback succeeds
Example fix
// before sops -e file.yaml # fails: fingerprint not in keyring // after gpg --import teammate.pub.asc && sops -e file.yaml
Defensive patterns
Strategy: validation
Validate before calling
fp := strings.ReplaceAll(fingerprint, " ", "")
out, err := exec.Command("gpg", "--homedir", gnupgHome, "--list-keys", fp).CombinedOutput()
if err != nil || !strings.Contains(string(out), fp) {
return fmt.Errorf("public key %s not present; run gpg --import first: %s", fp, out)
} Try / catch
if err := key.EncryptContext(ctx, dataKey); err != nil {
var agg interface{ Unwrap() []error }
if errors.As(err, &agg) || strings.Contains(err.Error(), "go-crypto/openpgp error") {
log.Warn("OpenPGP path failed; check keyring or rely on gpg fallback")
}
return err
} Prevention
- Import all fingerprints listed in .sops.yaml into the used GNUPGHOME before encrypting
- Remember GnuPG 2.1+ kbx keyrings may be unreadable by go-crypto; export legacy pubring.gpg if needed
- Check gpg --list-keys <fingerprint> in setup scripts
- Replace expired/revoked recipient keys promptly
When it happens
Trigger: Calling EncryptContext when the public keyring (pubRing or default pubring.gpg in the GnuPG home) cannot be read/parsed, or does not contain a usable public key for key.Fingerprint.
Common situations: Fingerprint in .sops.yaml never imported into the local keyring; GnuPG 2.1+ kbx format that go-crypto cannot read; GNUPGHOME pointing at an empty temp dir; expired/revoked recipient key.
Related errors
- could not encrypt data key with PGP key: %w
- GnuPG binary error: %w
- failed to encrypt sops data key with pgp: %s
- could not decrypt data key with PGP key: %w
- Could not initialize AES GCM encryption cipher: %s
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/b2da8eb9efb0fecf.
Report an issue: GitHub.