juicedata/juicefs · critical
format decrypt: %s
Error message
format decrypt: %s
What it means
createStorage requires the formatted volume's encrypted fields (e.g. object-storage keys) to be decrypted using the `--encrypt-key`/JFS_RSA_PASSPHRASE-derived key. Format.Decrypt() failed — typically RSA private-key parsing or decryption of stored secrets failed — so object storage cannot be initialized.
Source
Thrown at cmd/format.go:238
var bits uint
for s > 1 {
bits++
s >>= 1
}
s = s << bits
if s < min {
logger.Warnf("block size is too small: %s, use %s instead", humanize.IBytes(s), humanize.IBytes(min))
s = min
} else if s > max {
logger.Warnf("block size is too large: %s, use %s instead", humanize.IBytes(s), humanize.IBytes(max))
s = max
}
return s
}
func createStorage(format meta.Format) (object.ObjectStorage, error) {
if err := format.Decrypt(); err != nil {
return nil, fmt.Errorf("format decrypt: %s", err)
}
object.UserAgent = "JuiceFS-" + version.Version()
var blob object.ObjectStorage
var err error
if u, err := url.Parse(format.Bucket); err == nil {
values := u.Query()
if values.Get("tls-insecure-skip-verify") != "" {
var tlsSkipVerify bool
if tlsSkipVerify, err = strconv.ParseBool(values.Get("tls-insecure-skip-verify")); err != nil {
return nil, err
}
object.GetHttpClient().Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify = tlsSkipVerify
values.Del("tls-insecure-skip-verify")
u.RawQuery = values.Encode()
format.Bucket = u.String()
}
// Configure client TLS when params are providedView on GitHub (pinned to c9a67b23e8)
Solutions
- Set the correct encryption key env (JFS_RSA_PASSPHRASE for passphrase-protected keys, or the key file path) and retry.
- Confirm the RSA private key matches the one used at `juicefs format` time (compare public key fingerprint).
- Re-run `juicefs format` only if this is a new volume and stored secrets are not needed.
- Check metadata contents (`juicefs config <meta-url>`) to see which field fails to decrypt.
Example fix
// before juicefs gc sqlite3://myjfs.db # missing key -> format decrypt: ... // after export JFS_RSA_PASSPHRASE='my-passphrase' juicefs gc --encrypt-key /path/to/private.key sqlite3://myjfs.db
Defensive patterns
Strategy: try-catch
Validate before calling
// Check key material is present before creating storage
if os.Getenv("JFS_RSA_PASSPHRASE") == "" {
if _, err := os.Stat(keyPath); err != nil {
return fmt.Errorf("encryption key unavailable: set JFS_RSA_PASSPHRASE or provide key file")
}
} Type guard
func hasEncryptionKey() bool {
return os.Getenv("JFS_RSA_PASSPHRASE") != ""
} Try / catch
if err := format.Decrypt(); err != nil {
if strings.Contains(err.Error(), "format decrypt") {
// prompt user for passphrase / reload key and retry once
}
return fmt.Errorf("format decrypt: %s", err)
} Prevention
- Persist JFS_RSA_PASSPHRASE in the environment of every client accessing the volume.
- Back up the RSA key pair used at format time; store its fingerprint with volume docs.
- Use the same encrypted-key file across all mount/gc/fsck hosts.
- Test decryption with `juicefs config <meta-url>` before running maintenance commands.
When it happens
Trigger: Running format/gc/fsck/config/destroy against a metadata URL whose stored format contains encrypted fields, when the encryption key is missing, wrong, or corrupted; metadata was created with a different RSA key pair.
Common situations: JFS_RSA_PASSPHRASE wrong for the encrypted private key; ENCRYPT_KEY env var not set or points to wrong file; volume migrated between environments with different keys; corrupted meta format record.
Related errors
- passphrase is required to private key
- failed to parse PEM block containing the key
- decryt key: %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/3b8759627f4e7aae.
Report an issue: GitHub.