docker/cli · info

image prune has been cancelled

Error message

image prune has been cancelled

What it means

Without --force, runPrune() shows a confirmation prompt; if the user declines it returns this error wrapped in a cancelledErr type that implements Cancelled(). It represents intentional cancellation, not a failure of the prune API itself. The same type is returned by the dry-run pruneFn path during `docker system prune`.

Solutions

  1. Use --force/-f in automation to skip the prompt entirely
  2. Treat a cancelledErr (Cancelled()) as a benign no-op, not a hard failure
  3. Pre-confirm intent before invoking prune interactively

Example fix

// before
docker image prune   # then type n
// after
docker image prune -f
Defensive patterns

Strategy: type-guard

Type guard

// cancelledErr implements Cancelled() — detect via interface type assertion
type cancelled interface{ Cancelled() }

func isCancelled(err error) bool {
    var c cancelled
    return errors.As(err, &c)
}

Try / catch

spaceReclaimed, output, err := runPrune(ctx, cli, opts)
if err != nil {
    var c interface{ Cancelled() }
    if errors.As(err, &c) {
        // benign: user declined the prompt; do not treat as a hard failure
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: `docker image prune` (no -f) then answering "n" at the confirmation prompt; a dry-run prune path where Confirmed is false.

Common situations: Interactive use where the user aborts; automation that hits the prompt unexpectedly because it omitted --force.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/aa864e7a51539483. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/image/prune.go:86

	danglingWarning = `WARNING! This will remove all dangling images.
Are you sure you want to continue?`
)

func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) {
	pruneFilters := command.PruneFilters(dockerCli, options.filter.Value())
	pruneFilters.Add("dangling", strconv.FormatBool(!options.all))

	warning := danglingWarning
	if options.all {
		warning = allImageWarning
	}
	if !options.force {
		r, err := prompt.Confirm(ctx, dockerCli.In(), dockerCli.Out(), warning)
		if err != nil {
			return 0, "", err
		}
		if !r {
			return 0, "", cancelledErr{errors.New("image prune has been cancelled")}
		}
	}

	res, err := dockerCli.Client().ImagePrune(ctx, client.ImagePruneOptions{
		Filters: pruneFilters,
	})
	if err != nil {
		return 0, "", err
	}

	var sb strings.Builder
	if len(res.Report.ImagesDeleted) > 0 {
		sb.WriteString("Deleted Images:\n")
		for _, st := range res.Report.ImagesDeleted {
			if st.Untagged != "" {
				sb.WriteString("untagged: ")
				sb.WriteString(st.Untagged)
				sb.WriteByte('\n')

View on GitHub (pinned to 4f84911bfe)