dagger/dagger · error
failed to write diff
Error message
failed to write diff
What it means
In the non-compressed path of tryComputeOverlayBlob, the overlay upperdir diff is written directly into the buffered content writer via overlay.WriteUpperdir. Failure here (walking the diff or writing bytes) aborts with 'failed to write diff'. It is the uncompressed counterpart of 'failed to write compressed diff'.
Source
Thrown at engine/snapshots/blobs_linux.go:89
dgstr := digest.SHA256.Digester()
compressed, err := compressorFunc(bufW, mediaType)
if err != nil {
return emptyDesc, false, errors.Wrap(err, "failed to get compressed stream")
}
// Close ensure compressorFunc does some finalization works.
defer compressed.Close()
if err := overlay.WriteUpperdir(ctx, io.MultiWriter(compressed, dgstr.Hash()), upperdir, lower); err != nil {
return emptyDesc, false, errors.Wrap(err, "failed to write compressed diff")
}
if err := compressed.Close(); err != nil {
return emptyDesc, false, errors.Wrap(err, "failed to close compressed diff writer")
}
labels = map[string]string{
labelspkg.LabelUncompressed: dgstr.Digest().String(),
}
} else {
if err = overlay.WriteUpperdir(ctx, bufW, upperdir, lower); err != nil {
return emptyDesc, false, errors.Wrap(err, "failed to write diff")
}
}
if err := bufW.Flush(); err != nil {
return emptyDesc, false, errors.Wrap(err, "failed to flush diff")
}
var commitopts []content.Opt
if labels != nil {
commitopts = append(commitopts, content.WithLabels(labels))
}
dgst := cw.Digest()
if err := cw.Commit(ctx, 0, dgst, commitopts...); err != nil {
if !cerrdefs.IsAlreadyExists(err) {
return emptyDesc, false, errors.Wrap(err, "failed to commit")
}
}
if err := cw.Close(); err != nil {
return emptyDesc, false, errView on GitHub (pinned to 82ba2681db)
Solutions
- Read the wrapped inner error for the precise cause.
- Ensure the snapshot isn't being pruned concurrently while exporting (serialize export vs prune).
- Check content-store disk space and volume health.
- Re-run the build; clear corrupt snapshot state if errors persist.
Defensive patterns
Strategy: try-catch
Try / catch
_, ok, err := ref.tryComputeOverlayBlob(ctx, lower, upper, mediaType, refID, nil)
if err != nil && strings.Contains(err.Error(), "failed to write diff") {
log.Printf("uncompressed diff write failed: %v", errors.Cause(err))
// fall back to a fresh diff pass or walking differ after disk check
} Prevention
- Serialize export against prune so snapshot files aren't removed mid-walk
- Ensure read access and stable xattrs on upperdir files
- Keep free disk space for the uncompressed blob (largest case)
- Retry transient failures — snapshot mutation races are often one-off
When it happens
Trigger: overlay.WriteUpperdir(ctx, bufW, upperdir, lower) returning an error when no compressorFunc is configured — e.g. files vanishing during the walk, unreadable entries, write errors to the content-store writer, or context cancellation.
Common situations: Snapshot mutation/GC during diff; disk full on the content store; permission or xattr read failures on upperdir files; kernel/overlayfs quirks with whiteouts.
Related errors
- failed to write compressed diff
- failed to open writer
- failed to truncate writer
- failed to get compressed stream
- failed to close compressed diff writer
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/9e479f32766d9cc1.
Report an issue: GitHub.