docker/cli · error

cowardly refusing to save to a terminal. Use the -o flag or

Error message

cowardly refusing to save to a terminal. Use the -o flag or redirect

What it means

docker image save writes a binary tar archive to stdout when no --output/-o flag is given. In cli/command/image/save.go:71-73, if opts.output is empty and stdout is a terminal (dockerCLI.Out().IsTerminal()), the CLI refuses to dump raw tar bytes onto the TTY — which would spew garbage and can corrupt the terminal state. The 'cowardly refusing' guard forces you to name a file or redirect.

Source

Thrown at cli/command/image/save.go:73

func runSave(ctx context.Context, dockerCLI command.Cli, opts saveOptions) error {
	var options []client.ImageSaveOption

	platformList := []ocispec.Platform{}
	for _, p := range opts.platform {
		pp, err := platforms.Parse(p)
		if err != nil {
			return fmt.Errorf("invalid platform: %w", err)
		}
		platformList = append(platformList, pp)
	}
	if len(platformList) > 0 {
		options = append(options, client.ImageSaveWithPlatforms(platformList...))
	}

	var output io.Writer
	if opts.output == "" {
		if dockerCLI.Out().IsTerminal() {
			return errors.New("cowardly refusing to save to a terminal. Use the -o flag or redirect")
		}
		output = dockerCLI.Out()
	} else {
		writer, err := atomicwriter.New(opts.output, 0o600)
		if err != nil {
			return fmt.Errorf("failed to save image: %w", err)
		}
		defer writer.Close()
		output = writer
	}

	responseBody, err := dockerCLI.Client().ImageSave(ctx, opts.images, options...)
	if err != nil {
		return err
	}
	defer responseBody.Close()

	_, err = io.Copy(output, responseBody)

View on GitHub (pinned to e9452d6e78)

Solutions

  1. Use the output flag: docker save -o myimage.tar myimage:latest
  2. Or redirect stdout: docker save myimage:latest > myimage.tar
  3. Or pipe to a consumer: docker save myimage | gzip > myimage.tar.gz

Example fix

# before
docker save myimage:latest        # stdout is a terminal -> refused
# after
docker save -o myimage.tar myimage:latest
# or
docker save myimage:latest > myimage.tar

When it happens

Trigger: Running `docker save myimage` (or docker image save) in an interactive shell without -o and without redirecting/piping stdout, so stdout is a TTY.

Common situations: Forgetting -o on an interactive save; expecting docker save to take a filename positionally (all positional args are image names, not an output path); wrapper scripts that lose the intended redirection.

Related errors


AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01). Data as JSON: /data/errors/c41bd4cddd26283a.json. Report an issue: GitHub.