docker/compose · error

copying files to %s: %w

Error message

copying files to %s: %w

What it means

After the (optional) delete step, Tar.Sync streams a freshly built tar of the changed files into each container via LowLevelClient.Untar (docker's put-archive equivalent). Any failure copying/extracting is collected per container and joined into the final error. Two errors per container are possible (delete + copy); this one means the tar upload/extraction itself failed.

Source

Thrown at internal/sync/tar.go:112

	)

	eg.SetLimit(16) // arbitrary limit, adjust to taste :D
	for i := range containers {
		containerID := containers[i].ID
		tarReader := tarArchive(pathsToCopy)

		eg.Go(func() error {
			if len(deleteCmd) != 0 {
				if err := t.client.Exec(ctx, containerID, deleteCmd, nil); err != nil {
					errMu.Lock()
					errs = append(errs, fmt.Errorf("deleting paths in %s: %w", containerID, err))
					errMu.Unlock()
				}
			}

			if err := t.client.Untar(ctx, containerID, tarReader); err != nil {
				errMu.Lock()
				errs = append(errs, fmt.Errorf("copying files to %s: %w", containerID, err))
				errMu.Unlock()
			}
			return nil // don't fail-fast; collect all errors
		})
	}

	_ = eg.Wait()
	return errors.Join(errs...)
}

type ArchiveBuilder struct {
	tw *tar.Writer
	// A shared I/O buffer to help with file copying.
	copyBuf *bytes.Buffer
}

func NewArchiveBuilder(writer io.Writer) *ArchiveBuilder {
	tw := tar.NewWriter(writer)

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Verify the container is running: docker ps --filter id=<id from message>; restart it and retrigger the sync
  2. Check the container's rootfs space and the target container path is a writable directory: docker exec <id> df -h / <dest>
  3. Look at the joined sibling errors: an 'adding files to tar' error means the real failure was on the archive-builder goroutine (e.g. file vanished), fix the host side
  4. Inspect dockerd logs for the failed PUT /archive call if the container looks healthy
Defensive patterns

Strategy: retry

Validate before calling

// preflight before Untar loop: confirm containers are running and target dir writable
for _, c := range containers {
    if c.State != "running" { waitOrRestart(c.ID) }
}

Try / catch

// joined errors: identify 'copying files to <id>' entries, unwrap to the pipe/exec cause, restart that container, then re-invoke Sync once

Prevention

When it happens

Trigger: t.client.Untar(ctx, containerID, tarReader) failing: container gone or stopped between list and copy, disk full in the container, destination path is not a directory or is read-only, corrupted tar stream (writer goroutine errored, surfacing here as a pipe read error), or the container's archive-extract API returning an error.

Common situations: Containers restarting under 'docker compose up --watch' while a sync fires, full container overlay filesystems, syncing a file onto a path that is a mounted directory, or a host file disappearing mid-tar producing a pipe error propagated to the Untar side.

Related errors


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