juicedata/juicefs · error

%w: please set the 'JFS_RSA_PASSPHRASE' environment variable

Error message

%w: please set the 'JFS_RSA_PASSPHRASE' environment variable

What it means

When loading a config/cred file that was stored encrypted, the embedded RSA private key needs a passphrase; JFS_RSA_PASSPHRASE was not set, so ParsePrivateKeyFromPem returned ErrKeyNeedPasswd and `load` aborts with the same wrapped guidance as format.

Source

Thrown at cmd/load.go:115

func (r *reader) Close() error {
	if err := r.compressR.Close(); err != nil {
		return err
	}
	if r.encryptR != r.compressR {
		return r.encryptR.Close()
	}
	return nil
}

func open(src string, key string, algo string) (io.ReadCloser, error) {
	var r io.ReadCloser
	var ioErr error
	var fp io.ReadCloser
	if key != "" {
		privKey, err := object.ParsePrivateKeyFromPem([]byte(loadEncrypt(key)), []byte(os.Getenv("JFS_RSA_PASSPHRASE")))
		if err != nil {
			if errors.Is(err, object.ErrKeyNeedPasswd) {
				return nil, fmt.Errorf("%w: please set the 'JFS_RSA_PASSPHRASE' environment variable", err)
			}
			return nil, fmt.Errorf("parse private key: %s", err)
		}
		encryptor, err := object.NewDataEncryptor(object.NewKeyEncryptor(privKey), algo)
		if err != nil {
			return nil, err
		}
		if _, err := os.Stat(src); err != nil {
			return nil, fmt.Errorf("failed to stat %s: %s", src, err)
		}
		var srcAbsPath string
		srcAbsPath, err = filepath.Abs(src)
		if err != nil {
			return nil, fmt.Errorf("failed to get absolute path of %s: %s", src, err)
		}
		fileBlob, err := object.CreateStorage("file", strings.TrimSuffix(src, filepath.Base(srcAbsPath)), "", "", "")
		if err != nil {
			return nil, err

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Export JFS_RSA_PASSPHRASE with the key's passphrase before running load
  2. Use a secrets manager / env file: `set -a; . ./env; set +a; juicefs load ...`
  3. Regenerate the dump from an unencrypted source if the passphrase is lost is not possible — the key is required
  4. For systemd, add Environment=JFS_RSA_PASSPHRASE=... to the unit

Example fix

// before
juicefs load -i dump.json meta-url
// error: ... JFS_RSA_PASSPHRASE ...
// after
JFS_RSA_PASSPHRASE='secret' juicefs load -i dump.json meta-url
Defensive patterns

Strategy: validation

Validate before calling

if os.Getenv("JFS_RSA_PASSPHRASE") == "" {
    return fmt.Errorf("config is encrypted; set JFS_RSA_PASSPHRASE before load")
}

Type guard

func needsPassphrase(keyPem []byte) bool {
    return strings.Contains(string(keyPem), "ENCRYPTED")
}

Try / catch

_, err := load(cmd, args)
if err != nil && errors.Is(err, object.ErrKeyNeedPassphrase) {
    // re-run with JFS_RSA_PASSPHRASE set
}

Prevention

When it happens

Trigger: `juicefs load` (or convert) on a config file that was dumped from a volume using --encrypt-algo/--encrypt-key, executed in an environment without JFS_RSA_PASSPHRASE exported.

Common situations: Loading backups on a different host where the env var isn't set; CI pipelines and container images lacking the secret; shell without sourcing the env file.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/47473479d00a5c12. Report an issue: GitHub.