getsops/sops · error

GNUPGHOME must be an absolute path

Error message

GNUPGHOME must be an absolute path

What it means

GnuPGHome.Validate requires an absolute path because gpg's GNUPGHOME must be absolute to be unambiguous. If the value is non-empty but relative (e.g. "tmp/gnupg"), validation fails with this message. The home is never used for gpg operations in this state.

Source

Thrown at pgp/keysource.go:196

// 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 == "" {
		return fmt.Errorf("empty GNUPGHOME path")
	}
	if !filepath.IsAbs(d.String()) {
		return fmt.Errorf("GNUPGHOME must be an absolute path")
	}
	fi, err := os.Lstat(d.String())
	if err != nil {
		if os.IsNotExist(err) {
			return fmt.Errorf("GNUPGHOME does not exist")
		}
		return fmt.Errorf("cannot stat GNUPGHOME: %w", err)
	}
	if !fi.IsDir() {
		return fmt.Errorf("GNUGPHOME is not a directory")
	}
	if perm := fi.Mode().Perm(); perm != 0o700 {
		return fmt.Errorf("GNUPGHOME has invalid permissions: got %#o wanted %#o", perm, 0o700)
	}
	return nil
}

// String returns the GnuPGHome as a string. It does not Validate.

View on GitHub (pinned to 13442bb981)

Solutions

  1. Convert to an absolute path with filepath.Abs before assigning to GnuPGHome.
  2. Or use pgp.NewGnuPGHome() which always creates an absolute temp directory.
  3. If the path comes from configuration, validate/normalize it at config-load time.

Example fix

// before
home := pgp.GnuPGHome("gnupg-home")
// after
abs, err := filepath.Abs("gnupg-home")
if err != nil { return err }
home := pgp.GnuPGHome(abs)
Defensive patterns

Strategy: validation

Validate before calling

// Go
func absHome(p string) (pgp.GnuPGHome, error) {
  abs, err := filepath.Abs(p)
  if err != nil { return "", err }
  return pgp.GnuPGHome(abs), nil
}

Type guard

func absoluteHome(home pgp.GnuPGHome) bool { return filepath.IsAbs(home.String()) }

Try / catch

// Go
if err := home.Validate(); err != nil && strings.Contains(err.Error(), "must be an absolute path") {
  return fmt.Errorf("normalize GNUPGHOME with filepath.Abs before use: %w", err)
}

Prevention

When it happens

Trigger: Setting GnuPGHome from a user-supplied relative path or a config value without filepath.Abs, then calling Import, ImportContext, Cleanup, or ApplyToMasterKey.

Common situations: Passing a CLI/config argument like './gnupg-home' or 'gnupg' directly into GnuPGHome; composing paths without filepath.Abs in scripts or tests.

Related errors


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