{"record":{"id":"275aab523e96769e","repo":"juicedata/juicefs","slug":"parse-private-key-s-275aab","errorCode":null,"errorMessage":"parse private key: %s","messagePattern":"parse private key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/load.go","lineNumber":117,"sourceCode":"\t\treturn err\n\t}\n\tif r.encryptR != r.compressR {\n\t\treturn r.encryptR.Close()\n\t}\n\treturn nil\n}\n\nfunc open(src string, key string, algo string) (io.ReadCloser, error) {\n\tvar r io.ReadCloser\n\tvar ioErr error\n\tvar fp io.ReadCloser\n\tif key != \"\" {\n\t\tprivKey, err := object.ParsePrivateKeyFromPem([]byte(loadEncrypt(key)), []byte(os.Getenv(\"JFS_RSA_PASSPHRASE\")))\n\t\tif err != nil {\n\t\t\tif errors.Is(err, object.ErrKeyNeedPasswd) {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: please set the 'JFS_RSA_PASSPHRASE' environment variable\", err)\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"parse private key: %s\", err)\n\t\t}\n\t\tencryptor, err := object.NewDataEncryptor(object.NewKeyEncryptor(privKey), algo)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif _, err := os.Stat(src); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to stat %s: %s\", src, err)\n\t\t}\n\t\tvar srcAbsPath string\n\t\tsrcAbsPath, err = filepath.Abs(src)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get absolute path of %s: %s\", src, err)\n\t\t}\n\t\tfileBlob, err := object.CreateStorage(\"file\", strings.TrimSuffix(src, filepath.Base(srcAbsPath)), \"\", \"\", \"\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tblob := object.NewEncrypted(fileBlob, encryptor)","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/load.go#L99-L135","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\njuicefs load --encrypt-secret ./cert.pem sqlite3://test.db /tmp/backup.json\n// after\njuicefs load --encrypt-secret ./private.key sqlite3://test.db /tmp/backup.json  # private.key must be the RSA private key PEM","handlingStrategy":"validation","validationCode":"if !strings.Contains(pemBytes, \"PRIVATE KEY\") {\n    return fmt.Errorf(\"%s is not a private key PEM\", keyPath)\n}\nout, err := exec.Command(\"openssl\", \"pkey\", \"-in\", keyPath, \"-noout\").CombinedOutput()\nif err != nil { return fmt.Errorf(\"invalid key: %s\", out) }","typeGuard":null,"tryCatchPattern":"if err := runLoad(); err != nil {\n    if strings.Contains(err.Error(), \"parse private key\") {\n        log.Fatalf(\"check key file and JFS_RSA_PASSPHRASE: %v\", err)\n    }\n}","preventionTips":["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"],"tags":["crypto","rsa","pem","backup-restore"],"backgroundTag":"private-key-parse-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}