docker/compose · error

closing tar: %w

Error message

closing tar: %w

What it means

After all entries are written, tarArchive calls ArchiveBuilder.Close, whose tar.Writer.Close performs a final flush of the archive (padding/blocks). If that fails, the pipe is closed with 'closing tar: %w' — the archive is invalid and extraction on the container side will fail with this message.

Source

Thrown at internal/sync/tar.go:332

	})
	if err != nil {
		return nil, err
	}
	return result, nil
}

func tarArchive(ops []PathMapping) io.ReadCloser {
	pr, pw := io.Pipe()
	go func() {
		ab := NewArchiveBuilder(pw)
		err := ab.ArchivePathsIfExist(ops)
		if err != nil {
			_ = pw.CloseWithError(fmt.Errorf("adding files to tar: %w", err))
		} else {
			// propagate errors from the TarWriter::Close() because it performs a final
			// Flush() and any errors mean the tar is invalid
			if err := ab.Close(); err != nil {
				_ = pw.CloseWithError(fmt.Errorf("closing tar: %w", err))
			} else {
				_ = pw.Close()
			}
		}
	}()
	return pr
}

// Dedupe the entries with last-entry-wins semantics.
func dedupeEntries(entries []archiveEntry) []archiveEntry {
	seenIndex := make(map[string]int, len(entries))
	result := make([]archiveEntry, 0, len(entries))
	for i, entry := range entries {
		seenIndex[entry.header.Name] = i
	}
	for i, entry := range entries {
		if seenIndex[entry.header.Name] == i {
			result = append(result, entry)

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Check the wrapped cause: a closed-pipe error means the container-side reader aborted — diagnose that container (running? disk space? see error 102)
  2. Ensure containers stay alive and unpaused for the full sync duration
  3. Retry the sync once both sides are healthy; the archive cannot be salvaged mid-stream
  4. If dockerd reports extract errors, free container disk space before retrying
Defensive patterns

Strategy: try-catch

Validate before calling

null // final-flush failure is downstream of consumer health

Try / catch

// 'closing tar' -> check the pipe consumer (container) aborted first; restart it, then re-run Sync to rebuild the archive cleanly

Prevention

When it happens

Trigger: ab.Close() erroring in the producer goroutine: underlying pipe already closed with an error by a failed consumer (container died mid-Untar), or a prior write left the writer in an error state so the final flush reports it.

Common situations: Container stopped/paused mid-extract, closing the pipe reader; the writer's final flush then fails and the error is attributed to 'closing tar' even though the root cause is on the container side.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/351c92c5d7bfe614. Report an issue: GitHub.