GoogleContainerTools/skaffold · warning

pruning images: %w

Error message

pruning images: %w

What it means

localDaemon.Prune removes each listed image and records only the FIRST error encountered as errRt, wrapped as "pruning images: %w"; all images are still attempted. The returned error therefore represents one (the first) image-removal failure during a batch prune, typically a conflict because an image is in use.

Source

Thrown at pkg/skaffold/docker/image.go:746

		args = append(args, "--ssh", a.SSH)
	}

	return args, nil
}

func (l *localDaemon) Prune(ctx context.Context, images []string, pruneChildren bool) ([]string, error) {
	var pruned []string
	var errRt error
	for _, id := range images {
		resp, err := l.ImageRemove(ctx, id, client.ImageRemoveOptions{
			Force:         true,
			PruneChildren: pruneChildren,
		})
		if err == nil {
			pruned = append(pruned, id)
		} else if errRt == nil {
			// save the first error
			errRt = fmt.Errorf("pruning images: %w", err)
		}

		for _, r := range resp {
			if r.Deleted != "" {
				log.Entry(ctx).Debugf("deleted image %s\n", r.Deleted)
			}
			if r.Untagged != "" {
				log.Entry(ctx).Debugf("untagged image %s\n", r.Untagged)
			}
		}
	}
	return pruned, errRt
}

func (l *localDaemon) Stop(ctx context.Context, id string, stopTimeout *time.Duration) error {
	var so client.ContainerStopOptions
	if stopTimeout != nil {
		so.Timeout = util.Ptr[int](int(stopTimeout.Seconds()))

View on GitHub (pinned to a1189de023)

Solutions

  1. Stop and remove containers referencing the images: `docker ps -a --filter ancestor=<image>` then `docker rm`.
  2. Re-run the prune after containers are gone — remaining images usually prune cleanly.
  3. Enable force/children pruning at the call site (PruneChildren: true, Force in ImageRemoveOptions).
  4. Inspect which image failed from the wrapped error message and handle it individually.
Defensive patterns

Strategy: fallback

Validate before calling

// list images still in use before pruning
inUse := map[string]bool{}
cs, _ := client.ContainerList(ctx, client.ContainerListOptions{All: true})
for _, c := range cs { inUse[c.ImageID] = true }

Try / catch

pruned, err := daemon.Prune(ctx, images, true)
if err != nil && strings.Contains(err.Error(), "pruning images") {
    log.Printf("some images were pruned (%d ok); first failure: %v — remove containers and retry", len(pruned), err)
}

Prevention

When it happens

Trigger: Calling Prune(ctx, images, pruneChildren) where at least one ImageRemove fails (commonly errdefs.Conflict — image in use by a container) while others succeed; the first failure is surfaced in errRt.

Common situations: Pruning the local cache while a running or stopped container still uses an image, images tagged for a kind/minikube node, concurrent processes re-creating images mid-prune.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/e09c35064686633e. Report an issue: GitHub.