{"record":{"id":"3921811bc3d6c57f","repo":"getsops/sops","slug":"gnupg-binary-error-w","errorCode":null,"errorMessage":"GnuPG binary error: %w","messagePattern":"GnuPG binary error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgp/keysource.go","lineNumber":292,"sourceCode":"// fingerprint as the MasterKey.\nfunc (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {\n\tvar errs errSet\n\n\tif !key.disableOpenPGP {\n\t\topenpgpErr := key.encryptWithOpenPGP(dataKey)\n\t\tif openpgpErr == nil {\n\t\t\tlog.WithField(\"fingerprint\", key.Fingerprint).Info(\"Encryption succeeded\")\n\t\t\treturn nil\n\t\t}\n\t\terrs = append(errs, fmt.Errorf(\"github.com/ProtonMail/go-crypto/openpgp error: %w\", openpgpErr))\n\t}\n\n\tbinaryErr := key.encryptWithGnuPG(ctx, dataKey)\n\tif binaryErr == nil {\n\t\tlog.WithField(\"fingerprint\", key.Fingerprint).Info(\"Encryption succeeded\")\n\t\treturn nil\n\t}\n\terrs = append(errs, fmt.Errorf(\"GnuPG binary error: %w\", binaryErr))\n\n\tlog.WithField(\"fingerprint\", key.Fingerprint).Info(\"Encryption failed\")\n\treturn fmt.Errorf(\"could not encrypt data key with PGP key: %w\", errs)\n}\n\n// encryptWithOpenPGP attempts to encrypt the data key using OpenPGP with the\n// PGP key that belongs to Fingerprint. It sets EncryptedDataKey, or returns\n// an error.\nfunc (key *MasterKey) encryptWithOpenPGP(dataKey []byte) error {\n\tentity, err := key.retrievePubKey()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tencBuf := new(bytes.Buffer)\n\tarmorBuf, err := armor.Encode(encBuf, \"PGP MESSAGE\", nil)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/pgp/keysource.go#L274-L310","documentation":"If the OpenPGP attempt fails, EncryptContext falls back to running the gpg binary via encryptWithGnuPG; a failure there is appended as 'GnuPG binary error: %w'. It means the external gpg executable itself failed (non-zero exit) when trying to encrypt the data key. Both errors are later aggregated into the 'could not encrypt data key with PGP key' error.","triggerScenarios":"Calling EncryptContext when the gpg binary is missing/unusable (bad SOPS_GPG_EXEC path), the GnuPG home is invalid, the key is absent from the binary keyring, or gpg exits with an error (e.g. 'No public key', unusable pubkey).","commonSituations":"SOPS_GPG_EXEC pointing to a nonexistent binary; gpg not installed in a container; key not imported for the current user; expired recipient key causing gpg to refuse encryption.","solutions":["Check the wrapped cause for gpg's stderr (e.g. 'No public key', 'general error')","Verify the binary: gpg --version, and fix SOPS_GPG_EXEC if set to a wrong path","Import the recipient key: gpg --import <pubkey> and confirm with gpg --list-keys <fingerprint>","If the key is expired/revoked, extend or replace it and update .sops.yaml"],"exampleFix":"// before\nexport SOPS_GPG_EXEC=/usr/local/bin/gpg2  # binary does not exist\n// after\nunset SOPS_GPG_EXEC  # or export SOPS_GPG_EXEC=$(command -v gpg)","handlingStrategy":"validation","validationCode":"gpgExec := os.Getenv(\"SOPS_GPG_EXEC\")\nif gpgExec == \"\" { gpgExec = \"gpg\" }\nif _, err := exec.LookPath(gpgExec); err != nil {\n    return fmt.Errorf(\"gpg binary %q not found: %w\", gpgExec, err)\n}\nif out, err := exec.Command(gpgExec, \"--version\").CombinedOutput(); err != nil {\n    return fmt.Errorf(\"gpg not runnable: %v: %s\", err, out)\n}","typeGuard":null,"tryCatchPattern":"if err := key.EncryptContext(ctx, dataKey); err != nil {\n    if strings.Contains(err.Error(), \"GnuPG binary error\") {\n        // surface gpg stderr to the operator, do not retry blindly\n        log.Errorf(\"gpg fallback failed: %v\", err)\n    }\n    return err\n}","preventionTips":["Verify SOPS_GPG_EXEC points to an existing executable","Install gpg in containers/images used for sops","Import recipient keys into the binary keyring, not just files on disk","Check key expiry: gpg --list-keys shows [expired] flags"],"tags":["gnupg","gpg-binary","encryption","subprocess"],"backgroundTag":"gpg-command-failed","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}