juicedata/juicefs · error
failed to put checkpoint: %w
Error message
failed to put checkpoint: %w
What it means
Save() writes the marshalled checkpoint bytes to the destination storage under m.checkpointKey via dst.Put. This error wraps a Put failure, meaning the checkpoint could not be stored (network error, permission denied, bucket issues, storage backend 5xx). The checkpoint remains unsaved for this round and progress resumption may fall back to the last successful save.
Source
Thrown at pkg/sync/checkpoint.go:307
dstDelayDelMu.Lock()
ckpt.DstDelayDel = append([]string(nil), dstDelayDel...)
dstDelayDelMu.Unlock()
data, err := json.Marshal(ckpt)
m.multipartUploadStore.RUnlock()
for _, state := range ckpt.PrefixState {
state.RUnlock()
}
ckpt.Unlock()
if err != nil {
return fmt.Errorf("failed to marshal checkpoint: %w", err)
}
logger.Debugf("Saving checkpoint with %d prefixes, copied: %d, failed: %d",
prefixCount, ckpt.Stats.Copied, ckpt.Stats.Failed)
reader := bytes.NewReader(data)
if err := m.dst.Put(ctx, m.checkpointKey, reader); err != nil {
return fmt.Errorf("failed to put checkpoint: %w", err)
}
return nil
}
// ValidateConfig checks if checkpoint config matches current config
func (m *CheckpointManager) ValidateConfig(current *Config) bool {
old := m.checkpoint.Config
// Must match fields
if old.Start != current.Start || old.End != current.End {
logger.Warnf("Checkpoint config mismatch: start/end, old: %q/%q, current: %q/%q", old.Start, old.End, current.Start, current.End)
return false
}
if !slices.Equal(old.Include, current.Include) || !slices.Equal(old.Exclude, current.Exclude) {
logger.Warnf("Checkpoint config mismatch: include/exclude, old: %v/%v, current: %v/%v", old.Include, old.Exclude, current.Include, current.Exclude)
return falseView on GitHub (pinned to c9a67b23e8)
Solutions
- Retry the sync/save; Put failures are often transient — reduce checkpoint frequency if throttled
- Verify write credentials/permissions on the destination for the checkpoint key path
- Check destination storage availability and error details in the wrapped cause (%w)
- Use --dry-run or a smaller checkpoint interval to isolate whether the checkpoint key path itself is the problem
Defensive patterns
Strategy: retry
Validate before calling
// Pre-check write access to the destination
if _, err := m.dst.Head(ctx, m.checkpointKey); err != nil && !isNotFound(err) {
// destination may be misconfigured/unwritable; fix credentials before starting sync
} Try / catch
if err := mgr.Save(ctx); err != nil {
if strings.Contains(err.Error(), "failed to put checkpoint") {
time.Sleep(backoff)
_ = mgr.Save(ctx) // retry transient Put failures
}
} Prevention
- Grant the destination credentials PutObject permission on the sync prefix
- Reduce checkpoint save frequency to avoid object-store throttling
- Monitor destination bucket availability and disk space (for file:// destinations)
When it happens
Trigger: Periodic Save during a running Sync (or tests calling Save directly) where the destination object store rejects the Put: transient network failure, expired/insufficient credentials, bucket not writable, rate limiting, or the destination is offline.
Common situations: Long-running sync across unstable network to S3/OSS; IAM policy lacking PutObject on the checkpoint prefix; disk full when dst is a local path; object-store throttling on frequent checkpoint saves.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Failed to create bucket %s: %s, previous error: %s
- (max tries) upload block %s: %s (after %d tries)
- get %s: %s
- Unable to get endpoint of container %s: %s
- Can't connect to cluster %s: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/1a20f3448c8f9412.
Report an issue: GitHub.