juicedata/juicefs · error
json: %s
Error message
json: %s
What it means
In doInit, after resolving/updating the volume format, JuiceFS re-serializes it with json.MarshalIndent to persist a human-readable copy in Redis. If marshaling fails, this "json: %s" error is returned (pkg/meta/redis.go:377). Marshal of a plain Format struct essentially cannot fail in practice, so hitting this indicates a deeply anomalous state (e.g., unsupported value slipped into the struct).
Source
Thrown at pkg/meta/redis.go:377
// remove user group quota as they are outdated
_, err := m.rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Del(ctx, m.userQuotaKey(), m.userQuotaUsedSpaceKey(), m.userQuotaUsedInodesKey(),
m.groupQuotaKey(), m.groupQuotaUsedSpaceKey(), m.groupQuotaUsedInodesKey())
m.genLog(ctx, pipe, time.Now(), "INIT_ENABLE_USERGROUPQUOTA()")
return nil
})
if err != nil {
return errors.Wrap(err, "remove 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)
}
ts := time.Now().Unix()
attr := &Attr{
Typ: TypeDirectory,
Atime: ts,
Mtime: ts,
Ctime: ts,
Nlink: 2,
Length: 4 << 10,
Parent: RootInode,
}
if format.TrashDays > 0 {
attr.Mode = 0555
if err = m.rdb.SetNX(ctx, m.inodeKey(TrashInode), m.marshal(attr), 0).Err(); err != nil {
return err
}
}
if err = m.rdb.Set(ctx, m.setting(), data, 0).Err(); err != nil {View on GitHub (pinned to c9a67b23e8)
Solutions
- If running a patched/custom build, check recently added Format fields for unsupported JSON types (chan, func, complex, NaN floats).
- Retry the format command once — transient memory/allocator issues are effectively the only other cause.
- If it reproduces on a stock build, file a bug with the full error string and version (juicefs --version).
Example fix
// before (hypothetical patched Format)
type Format struct {
Name string
Hook func(string) // not JSON-marshalable
}
// after
type Format struct {
Name string
HookName string // marshalable representation
} Defensive patterns
Strategy: try-catch
Try / catch
if err := initFormat(...); err != nil {
if strings.HasPrefix(err.Error(), "json: ") {
// practically indicates a non-marshalable field; treat as a bug,
// report with juicefs --version and the full error string
}
return err
} Prevention
- Use stock JuiceFS releases rather than locally patched Format structs.
- If you patch pkg/meta, keep all Format fields JSON-marshalable.
- Report reproducible occurrences upstream with the version and error text.
When it happens
Trigger: json.MarshalIndent(format, ...) returns an error while initializing the volume — practically only if the Format struct contains a value that cannot be marshaled (unsupported type such as a channel/func or a NaN-ish number introduced by modified or patched code).
Common situations: Custom/patched JuiceFS builds that added a field of an unmarshalable type to Format; otherwise essentially never seen in stock builds — report as a bug if encountered.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- database %s is used by volume %s
- load setting: %s
- new session: %s
- load user/group quotas: %w
- existing format is broken: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/4fcfcd16906a603b.
Report an issue: GitHub.