{"record":{"id":"02b7163d4f303d94","repo":"getsops/sops","slug":"cannot-read-armored-key-data-from-file-w","errorCode":null,"errorMessage":"cannot read armored key data from file: %w","messagePattern":"cannot read armored key data from file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgp/keysource.go","lineNumber":174,"sourceCode":"\t\t\t\tfmt.Fprintf(&sb, \" (%s)\", errStr)\n\t\t\t}\n\t\t\tfmt.Fprintf(&sb, \": %s\", stderrStr)\n\t\t} else if len(errStr) > 0 {\n\t\t\tfmt.Fprintf(&sb, \": %s\", errStr)\n\t\t}\n\t\treturn errors.New(sb.String())\n\t}\n\treturn nil\n}\n\n// ImportFile attempts to import the armored key file into the GnuPGHome\n// keyring.\n// It returns an error if the GnuPGHome does not pass Validate, or if the\n// import failed.\nfunc (d GnuPGHome) ImportFile(path string) error {\n\tb, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot read armored key data from file: %w\", err)\n\t}\n\treturn d.Import(b)\n}\n\n// Cleanup deletes the GnuPGHome if it passes Validate.\n// It returns an error if the GnuPGHome does not pass Validate, or if the\n// removal failed.\nfunc (d GnuPGHome) Cleanup() error {\n\tif err := d.Validate(); err != nil {\n\t\treturn err\n\t}\n\treturn os.RemoveAll(d.String())\n}\n\n// Validate ensures the GnuPGHome is a valid GnuPG home directory path.\n// When validation fails, it returns a descriptive reason as error.\nfunc (d GnuPGHome) Validate() error {\n\tif d == \"\" {","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/pgp/keysource.go#L156-L192","documentation":"GnuPGHome.ImportFile reads the armored key file with os.ReadFile before importing it; if the read fails, this error wraps it and the import is never attempted. This is a plain file-read failure - the key data could not be loaded from disk.","triggerScenarios":"Calling ImportFile with a path that does not exist, is a directory, lacks read permission, or (on some systems) is too large/locked.","commonSituations":"Typo in the key file path; passing a directory instead of the .asc file; file was generated in a previous step that failed; CI artifact not downloaded; permission change after key export.","solutions":["Verify the path exists and is a regular file: `ls -l <path>`; fix typos or point to the actual .asc file.","Check read permissions on the file and its parent directories.","Ensure the key export step (e.g. `gpg --armor --export`) succeeded before calling ImportFile.","If the file may be transient, read it yourself with os.ReadFile and pass bytes via Import for better error handling."],"exampleFix":"// before\nerr := home.ImportFile(\"keys/pubkey.asc\") // wrong relative path\n// after\nabs, _ := filepath.Abs(\"./keys/pubkey.asc\")\nif _, err := os.Stat(abs); err != nil { return err }\nerr := home.ImportFile(abs)","handlingStrategy":"validation","validationCode":"// Go\nfunc importFileSafe(home pgp.GnuPGHome, path string) error {\n  fi, err := os.Stat(path)\n  if err != nil { return fmt.Errorf(\"key file %q: %w\", path, err) }\n  if fi.IsDir() { return fmt.Errorf(\"%q is a directory, not a key file\", path) }\n  return home.ImportFile(path)\n}","typeGuard":null,"tryCatchPattern":"// Go\nif err := home.ImportFile(path); err != nil {\n  if strings.Contains(err.Error(), \"cannot read armored key data from file\") {\n    return fmt.Errorf(\"check key file path/permissions: %w\", err)\n  }\n  return err\n}","preventionTips":["Resolve key file paths to absolute with filepath.Abs before use","Check os.Stat for existence and non-directory before importing","Fail earlier if the key-export step produced no file","Verify file permissions in CI artifacts are readable by the running user"],"tags":["gnupg","pgp","filesystem","file-not-found"],"backgroundTag":"file-read-failed","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}