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

  1. Read the wrapped cause: only fields allowed by Format.update can change; revert unintended flags to match the existing volume.
  2. If the change is intentionally permitted (e.g. updating secrets/capacity), re-run with `--force`.
  3. 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

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


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/9c07a71d526fd8a2. Report an issue: GitHub.