juicedata/juicefs · error
parse private key: %s
Error message
parse private key: %s
What it means
When loading an encrypted metadata backup, `juicefs load` parses the RSA private key from a PEM file (or KMS) via object.ParsePrivateKeyFromPem to build a decryptor. If the PEM data cannot be parsed as a private key — and it is not merely a passphrase-protected key — the command aborts with `parse private key: <underlying error>`. This means the key material itself is unreadable, wrong, or in an unsupported format.
Source
Thrown at cmd/load.go:117
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
}
blob := object.NewEncrypted(fileBlob, encryptor)View on GitHub (pinned to c9a67b23e8)
Solutions
- Inspect the key file with `openssl pkey -in <keyfile> -noout -text` to confirm it is a valid RSA private key
- Re-export the original RSA private key used at `juicefs format` time and save it as a PEM file
- Verify you passed the key path/URI to the correct flag and that the file was downloaded completely (check size)
- If the key is passphrase-protected, set JFS_RSA_PASSPHRASE so the correct ErrKeyNeedPasswd branch is taken instead
Example fix
// before juicefs load --encrypt-secret ./cert.pem sqlite3://test.db /tmp/backup.json // after juicefs load --encrypt-secret ./private.key sqlite3://test.db /tmp/backup.json # private.key must be the RSA private key PEM
Defensive patterns
Strategy: validation
Validate before calling
if !strings.Contains(pemBytes, "PRIVATE KEY") {
return fmt.Errorf("%s is not a private key PEM", keyPath)
}
out, err := exec.Command("openssl", "pkey", "-in", keyPath, "-noout").CombinedOutput()
if err != nil { return fmt.Errorf("invalid key: %s", out) } Try / catch
if err := runLoad(); err != nil {
if strings.Contains(err.Error(), "parse private key") {
log.Fatalf("check key file and JFS_RSA_PASSPHRASE: %v", err)
}
} Prevention
- Validate the key with openssl before using it in load/dump
- Store the exact RSA private key generated at format time, not a certificate
- Keep key and passphrase (JFS_RSA_PASSPHRASE) together in your secrets management
- Checksum key files after copying to detect truncation
When it happens
Trigger: Running `juicefs load`/`convert` with --encrypt-secret (the `key` flag) pointing to a PEM file that is corrupt, truncated, not a PEM block, contains a public key instead of a private key, or is in an unsupported format (e.g. PKCS1 vs PKCS8 issues handled incorrectly). Also triggered when the key was re-uploaded/re-exported incorrectly from a KMS.
Common situations: Copying the key file and accidentally truncating it; exporting a certificate or public key instead of the RSA private key; passing a path to a config file instead of the key; the PEM file being empty or containing whitespace/HTML from a web console copy-paste; JFS_RSA_PASSPHRASE set but the key is simply invalid.
Related errors
- failed to parse PEM block containing the key
- cannot decode encrypted private keys: %v
- The entry of the root inode was not found
- not implemented, use kvMeta.LoadMetaV2 instead
- passphrase is required to private key
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/275aab523e96769e.
Report an issue: GitHub.