juicedata/juicefs · error
update format
Error message
update format
What it means
In kvMeta.doInit (pkg/meta/tkv.go:557), after optional cleanups the new Format is reconciled with the stored one via format.update(&old, force); any validation failure (e.g. changing protected fields like Name/UUID/storage settings, or invalid capacity/inodes) is wrapped as "update format". This is the user-facing rejection when `juicefs format` tries an impermissible change on an existing volume.
Source
Thrown at pkg/meta/tkv.go:557
return errors.Wrap(err, "delete dir stats")
}
}
if !old.UserGroupQuota && format.UserGroupQuota {
// remove user group quota as they are outdated
userPrefix := m.fmtKey("QU")
groupPrefix := m.fmtKey("QG")
err := m.txn(Background(), func(tx *kvTxn) error {
tx.deleteKeys(userPrefix)
tx.deleteKeys(groupPrefix)
m.genLog(tx, time.Now(), "INIT_ENABLE_USERGROUPQUOTA()")
return nil
})
if err != nil {
return errors.Wrap(err, "delete user group quota")
}
}
if err = format.update(&old, force); err != nil {
return errors.Wrap(err, "update format")
}
}
data, err := json.MarshalIndent(format, "", "")
if err != nil {
return fmt.Errorf("json: %s", err)
}
m.setFormat(format)
ts := time.Now().Unix()
attr := &Attr{
Typ: TypeDirectory,
Atime: ts,
Mtime: ts,
Ctime: ts,
Nlink: 2,
Length: 4 << 10,
Parent: RootInode,View on GitHub (pinned to c9a67b23e8)
Solutions
- Read the wrapped cause: only fields allowed by Format.update can change; revert unintended flags to match the existing volume.
- If the change is intentionally permitted (e.g. updating secrets/capacity), re-run with `--force`.
- To change immutable fields (storage backend, name), create a new volume and migrate data with `juicefs sync` instead of re-formatting.
Example fix
// before juicefs format redis://host:6379/1 jfs --storage s3 --bucket s3://new-bucket // after juicefs format redis://host:6379/1 jfs --capacity 1024 --force # only permitted fields, explicit confirmation
Defensive patterns
Strategy: validation
Validate before calling
// diff intended format against the live one before formatting
old, _ := loadFormat(metaURL)
if old.Storage != newFormat.Storage || old.Bucket != newFormat.Bucket {
return errors.New("storage/bucket is immutable; create a new volume and sync data")
} Try / catch
if err := formatVolume(); err != nil {
if strings.Contains(err.Error(), "update format") {
// revert disallowed flags or re-run with --force for permitted changes
}
} Prevention
- Read `juicefs status <meta-url>` first and only change fields permitted by Format.update.
- Use --force deliberately and only for allowed in-place updates (e.g. capacity, secrets).
- To move storage backends, create a new volume and migrate with `juicefs sync` instead of re-formatting.
When it happens
Trigger: Re-running `juicefs format` against an existing volume with changed settings (e.g. different storage bucket, capacity, or secrets) without --force; or passing values the Format update validation rejects (negative capacity, conflicting flags).
Common situations: Operators attempting to move object storage or shrink capacity in place; typo'd flags re-applying a format; automation replaying a format manifest differing from the live volume; forgetting --force for allowed updates.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- scan dir stats
- delete dir stats
- delete user group quota
- tier should be between 0 and 3
- Invalid trash days: %d
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/9c07a71d526fd8a2.
Report an issue: GitHub.