docker/cli · warning · cancelledErr

volume prune has been cancelled

Error message

volume prune has been cancelled

What it means

Returned by runPrune (volume/prune.go:88-90) when the user is shown the prune warning prompt and answers 'no' (or anything not interpreted as confirmation) and --force was not given. The error is wrapped in cancelledErr (which satisfies Cancelled()), signalling an intentional cancellation rather than a failure.

Solutions

  1. If you intended to prune, re-run and answer 'y' at the prompt, or pass --force/-f to skip it.
  2. In automation, always pass '-f' so no prompt is issued.
  3. Treat a cancelledErr as expected (not a hard failure) in scripts - check the Cancelled() marker rather than treating exit code as fatal.

Example fix

# before
docker volume prune          # then type n

# after (automation)
docker volume prune --force
Defensive patterns

Strategy: validation

Validate before calling

// For non-interactive runs, pass --force to avoid the prompt entirely.
func volumePruneCmd(force bool) []string {
    if force {
        return []string{"volume", "prune", "--force"}
    }
    return []string{"volume", "prune"}
}

Type guard

// isCancelled reports whether an error from prune is a user cancellation (not a failure).
// Mirror the CLI's cancelledErr.Cancelled() marker.
type cancelled interface{ Cancelled() bool }
func isCancelled(err error) bool {
    var c cancelled
    return errors.As(err, &c) // adapt to your error-wrapping library
}

Try / catch

// Treat cancellation as an expected, non-fatal outcome.
if _, err := runPrune(ctx, cli, opts); err != nil {
    if isCancelled(err) {
        // user declined; proceed without pruning
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Running 'docker volume prune' (without -f/--force) and typing 'n' or an empty/invalid answer at the 'Are you sure you want to continue?' prompt (prune.go:84 uses prompt.Confirm).

Common situations: Interactive session where the user hesitates. Non-interactive piping of 'n' into stdin. A CI/automation step that forgot --force and gets a non-yes answer.

Related errors


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

Appendix: source

Thrown at cli/command/volume/prune.go:89

func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, _ error) {
	pruneFilters := command.PruneFilters(dockerCli, options.filter.Value())

	warning := unusedVolumesWarning
	if options.all {
		if _, ok := pruneFilters["all"]; ok {
			return 0, "", invalidParamErr{errors.New("conflicting options: cannot specify both --all and --filter all=1")}
		}
		pruneFilters.Add("all", "true")
		warning = allVolumesWarning
	}
	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("volume prune has been cancelled")}
		}
	}

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

	var out strings.Builder
	if len(res.Report.VolumesDeleted) > 0 {
		out.WriteString("Deleted Volumes:\n")
		for _, id := range res.Report.VolumesDeleted {
			out.WriteString(id + "\n")
		}
		spaceReclaimed = res.Report.SpaceReclaimed
	}

View on GitHub (pinned to 4f84911bfe)