{"record":{"id":"366b874f22254b89","repo":"juicedata/juicefs","slug":"failed-to-parse-pem-block-containing-the-key","errorCode":null,"errorMessage":"failed to parse PEM block containing the key","messagePattern":"failed to parse PEM block containing the key","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/encrypt.go","lineNumber":70,"sourceCode":"\t}\n\tif passphrase != \"\" {\n\t\tvar err error\n\t\t// nolint:staticcheck\n\t\tblock, _ = x509.EncryptPEMBlock(rand.Reader, block.Type, buf, []byte(passphrase), x509.PEMCipherAES256)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\tprivPEM := pem.EncodeToMemory(block)\n\treturn string(privPEM)\n}\n\nvar ErrKeyNeedPasswd = errors.New(\"passphrase is required to private key\")\n\nfunc ParsePrivateKeyFromPem(enc []byte, passphrase []byte) (any, error) {\n\tblock, _ := pem.Decode(enc)\n\tif block == nil {\n\t\treturn nil, errors.New(\"failed to parse PEM block containing the key\")\n\t}\n\n\tbuf := block.Bytes\n\tif len(passphrase) == 0 {\n\t\t// nolint:staticcheck\n\t\tif strings.Contains(block.Headers[\"Proc-Type\"], \"ENCRYPTED\") && x509.IsEncryptedPEMBlock(block) {\n\t\t\treturn nil, ErrKeyNeedPasswd\n\t\t}\n\t\tif strings.Contains(block.Type, \"ENCRYPTED\") {\n\t\t\treturn nil, ErrKeyNeedPasswd\n\t\t}\n\t} else {\n\t\tvar err error\n\t\t// nolint:staticcheck\n\t\tbuf, err = x509.DecryptPEMBlock(block, passphrase)\n\t\tif err != nil {\n\t\t\tif err == x509.IncorrectPasswordError {\n\t\t\t\treturn nil, err","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/encrypt.go#L52-L88","documentation":"pem.Decode returned nil for the input bytes in ParsePrivateKeyFromPem, meaning they do not form a recognizable PEM block (missing BEGIN/END markers, corrupted base64, or wrong DER encoding). This is a validation guard rejecting malformed key material before any decryption is attempted.","triggerScenarios":"Passing an empty/garbled encrypt key file, a raw DER key without PEM armor, a file with whitespace/HTML or wrong content, or a path read that returned an error page/empty string to ParsePrivateKeyFromPem (via format, load, or open of an encrypted store).","commonSituations":"Misconfigured --encrypt-key pointing to the public key or to a text file; copy-paste that lost the BEGIN/END lines; cloud IAM cred file accidentally used as the key; truncated download.","solutions":["Inspect the key file: it must contain '-----BEGIN RSA PRIVATE KEY-----' (or similar) PEM blocks; regenerate with juicefs format --encrypt-algo rsa-keygen if lost.","Check the file path passed as the encrypt key resolves to the private key, not the public key or credentials file.","Re-copy the key ensuring headers/footers and newlines are intact (no truncation, no HTML wrapping).","If the key is DER-encoded, convert it: openssl rsa -in key.der -inform DER -out key.pem."],"exampleFix":"// before (garbled file)\nprivKey, err := object.ParsePrivateKeyFromPem([]byte(read(cfg.Key)), []byte(os.Getenv(\"JFS_RSA_PASSPHRASE\")))\n// after (validate PEM presence first)\nif !bytes.Contains(keyData, []byte(\"-----BEGIN\")) {\n    return nil, fmt.Errorf(\"%s is not a PEM-encoded private key\", cfg.Key)\n}\nprivKey, err := object.ParsePrivateKeyFromPem(keyData, []byte(os.Getenv(\"JFS_RSA_PASSPHRASE\")))","handlingStrategy":"validation","validationCode":"func isPEM(b []byte) bool {\n    block, _ := pem.Decode(b)\n    return block != nil\n}\n// before use:\nif !isPEM(keyData) {\n    return fmt.Errorf(\"encrypt key is not PEM-encoded\")\n}","typeGuard":"func validPrivateKeyPEM(b []byte) bool {\n    block, _ := pem.Decode(b)\n    return block != nil && strings.Contains(block.Type, \"PRIVATE KEY\")\n}","tryCatchPattern":"privKey, err := object.ParsePrivateKeyFromPem(enc, pass)\nif err != nil {\n    if errors.Is(err, object.ErrKeyNeedPasswd) { /* passphrase issue */ }\n    return fmt.Errorf(\"invalid encrypt key file: %w\", err)\n}","preventionTips":["Point --encrypt-key at the private key PEM, never the public key or credentials file.","Validate the PEM header with pem.Decode before use.","Copy keys preserving line structure; avoid HTML/email mangling of BEGIN/END lines."],"tags":["encryption","rsa","pem","key-parsing"],"backgroundTag":"invalid-argument-format","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"}