juicedata/juicefs · error
failed to parse PEM block containing the key
Error message
failed to parse PEM block containing the key
What it means
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.
Source
Thrown at pkg/object/encrypt.go:70
}
if passphrase != "" {
var err error
// nolint:staticcheck
block, _ = x509.EncryptPEMBlock(rand.Reader, block.Type, buf, []byte(passphrase), x509.PEMCipherAES256)
if err != nil {
panic(err)
}
}
privPEM := pem.EncodeToMemory(block)
return string(privPEM)
}
var ErrKeyNeedPasswd = errors.New("passphrase is required to private key")
func ParsePrivateKeyFromPem(enc []byte, passphrase []byte) (any, error) {
block, _ := pem.Decode(enc)
if block == nil {
return nil, errors.New("failed to parse PEM block containing the key")
}
buf := block.Bytes
if len(passphrase) == 0 {
// nolint:staticcheck
if strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED") && x509.IsEncryptedPEMBlock(block) {
return nil, ErrKeyNeedPasswd
}
if strings.Contains(block.Type, "ENCRYPTED") {
return nil, ErrKeyNeedPasswd
}
} else {
var err error
// nolint:staticcheck
buf, err = x509.DecryptPEMBlock(block, passphrase)
if err != nil {
if err == x509.IncorrectPasswordError {
return nil, errView on GitHub (pinned to c9a67b23e8)
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.
Example fix
// before (garbled file)
privKey, err := object.ParsePrivateKeyFromPem([]byte(read(cfg.Key)), []byte(os.Getenv("JFS_RSA_PASSPHRASE")))
// after (validate PEM presence first)
if !bytes.Contains(keyData, []byte("-----BEGIN")) {
return nil, fmt.Errorf("%s is not a PEM-encoded private key", cfg.Key)
}
privKey, err := object.ParsePrivateKeyFromPem(keyData, []byte(os.Getenv("JFS_RSA_PASSPHRASE"))) Defensive patterns
Strategy: validation
Validate before calling
func isPEM(b []byte) bool {
block, _ := pem.Decode(b)
return block != nil
}
// before use:
if !isPEM(keyData) {
return fmt.Errorf("encrypt key is not PEM-encoded")
} Type guard
func validPrivateKeyPEM(b []byte) bool {
block, _ := pem.Decode(b)
return block != nil && strings.Contains(block.Type, "PRIVATE KEY")
} Try / catch
privKey, err := object.ParsePrivateKeyFromPem(enc, pass)
if err != nil {
if errors.Is(err, object.ErrKeyNeedPasswd) { /* passphrase issue */ }
return fmt.Errorf("invalid encrypt key file: %w", err)
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- passphrase is required to private key
- decryt key: %s
- format decrypt: %s
- %w: please set the 'JFS_RSA_PASSPHRASE' environment variable
- parse private key: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/366b874f22254b89.
Report an issue: GitHub.