juicedata/juicefs · error
failed to unmarshal checkpoint: %w
Error message
failed to unmarshal checkpoint: %w
What it means
Load() unmarshals the checkpoint bytes into the Checkpoint struct with encoding/json. This error wraps json.Unmarshal failures, meaning the checkpoint object was read but its content is not valid JSON or does not match the Checkpoint schema (e.g. wrong format, corrupted, or written by an incompatible version). Load treats the checkpoint as unusable and returns without setting m.checkpoint.
Source
Thrown at pkg/sync/checkpoint.go:257
go m.cleanupCheckpointTmp()
obj, err := m.dst.Get(ctx, m.checkpointKey, 0, -1)
if err != nil {
// head to wrap 404 as os.ErrNotExist
if _, err := m.dst.Head(ctx, m.checkpointKey); os.IsNotExist(err) {
return nil, err
}
return nil, err
}
defer obj.Close()
data, err := io.ReadAll(obj)
if err != nil {
return nil, fmt.Errorf("failed to read checkpoint: %w", err)
}
var ckpt Checkpoint
if err := json.Unmarshal(data, &ckpt); err != nil {
return nil, fmt.Errorf("failed to unmarshal checkpoint: %w", err)
}
if ckpt.MultipartUploads == nil {
ckpt.MultipartUploads = make(map[string]*multipartUploadState)
}
m.checkpoint = &ckpt
m.multipartUploadStore.reset(ckpt.MultipartUploads)
return &ckpt, nil
}
// Save saves checkpoint to object storage
func (m *CheckpointManager) Save(ckpt *Checkpoint) error {
if ckpt.Config != nil && ckpt.Config.Dry {
return nil
}
m.saveMu.Lock()
defer m.saveMu.Unlock()
if m.statsUpdater != nil {View on GitHub (pinned to c9a67b23e8)
Solutions
- Delete/overwrite the stale checkpoint object so Sync starts fresh (or use the force-reset behavior to ignore the existing checkpoint)
- Confirm the checkpoint was written by a compatible JuiceFS version; align client versions across workers
- Inspect the object content at the checkpoint key to confirm it is valid JSON matching the Checkpoint schema
Defensive patterns
Strategy: validation
Validate before calling
// Validate checkpoint JSON before handing it to Load-equivalent logic
data, _ := io.ReadAll(obj)
if !json.Valid(data) {
// invalid checkpoint: delete it or force a fresh start
} Try / catch
ckpt, err := mgr.Load(ctx)
if err != nil {
if strings.Contains(err.Error(), "failed to unmarshal checkpoint") {
logger.Warnf("ignoring incompatible/corrupt checkpoint: %v", err)
ckpt = nil
}
} Prevention
- Run mixed-version workers only with compatible JuiceFS versions
- Never hand-edit or repurpose objects stored at the checkpoint key
- Use force-reset when you know the existing checkpoint is from an incompatible run
When it happens
Trigger: Sync resumes and Load reads the object at m.checkpointKey, but json.Unmarshal fails because the object content is not a valid Checkpoint JSON document — file written by a different tool/format, schema drift between JuiceFS versions, or truncated/partial JSON from an interrupted Save.
Common situations: Upgrading JuiceFS between versions where Checkpoint fields changed; checkpoint object corrupted in the object store; user accidentally pointed the sync at an object that isn't a checkpoint; interrupted previous run left partial data.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- json: %s
- failed to read checkpoint: %w
- failed to marshal checkpoint: %w
- failed to parse config
- failed to unmarshal footer: %w
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/40e9e3500c6f0d12.
Report an issue: GitHub.