getsops/sops · error

cannot read armored key data from file: %w

Error message

cannot read armored key data from file: %w

What it means

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.

Source

Thrown at pgp/keysource.go:174

				fmt.Fprintf(&sb, " (%s)", errStr)
			}
			fmt.Fprintf(&sb, ": %s", stderrStr)
		} else if len(errStr) > 0 {
			fmt.Fprintf(&sb, ": %s", errStr)
		}
		return errors.New(sb.String())
	}
	return nil
}

// ImportFile attempts to import the armored key file into the GnuPGHome
// keyring.
// It returns an error if the GnuPGHome does not pass Validate, or if the
// import failed.
func (d GnuPGHome) ImportFile(path string) error {
	b, err := os.ReadFile(path)
	if err != nil {
		return fmt.Errorf("cannot read armored key data from file: %w", err)
	}
	return d.Import(b)
}

// Cleanup deletes the GnuPGHome if it passes Validate.
// It returns an error if the GnuPGHome does not pass Validate, or if the
// removal failed.
func (d GnuPGHome) Cleanup() error {
	if err := d.Validate(); err != nil {
		return err
	}
	return os.RemoveAll(d.String())
}

// Validate ensures the GnuPGHome is a valid GnuPG home directory path.
// When validation fails, it returns a descriptive reason as error.
func (d GnuPGHome) Validate() error {
	if d == "" {

View on GitHub (pinned to 13442bb981)

Solutions

  1. Verify the path exists and is a regular file: `ls -l <path>`; fix typos or point to the actual .asc file.
  2. Check read permissions on the file and its parent directories.
  3. Ensure the key export step (e.g. `gpg --armor --export`) succeeded before calling ImportFile.
  4. If the file may be transient, read it yourself with os.ReadFile and pass bytes via Import for better error handling.

Example fix

// before
err := home.ImportFile("keys/pubkey.asc") // wrong relative path
// after
abs, _ := filepath.Abs("./keys/pubkey.asc")
if _, err := os.Stat(abs); err != nil { return err }
err := home.ImportFile(abs)
Defensive patterns

Strategy: validation

Validate before calling

// Go
func importFileSafe(home pgp.GnuPGHome, path string) error {
  fi, err := os.Stat(path)
  if err != nil { return fmt.Errorf("key file %q: %w", path, err) }
  if fi.IsDir() { return fmt.Errorf("%q is a directory, not a key file", path) }
  return home.ImportFile(path)
}

Try / catch

// Go
if err := home.ImportFile(path); err != nil {
  if strings.Contains(err.Error(), "cannot read armored key data from file") {
    return fmt.Errorf("check key file path/permissions: %w", err)
  }
  return err
}

Prevention

When it happens

Trigger: Calling ImportFile with a path that does not exist, is a directory, lacks read permission, or (on some systems) is too large/locked.

Common situations: 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.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01). Data as JSON: /api/errors/02b7163d4f303d94. Report an issue: GitHub.