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
- Use the output flag: docker save -o myimage.tar myimage:latest
- Or redirect stdout: docker save myimage:latest > myimage.tar
- 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
- cowardly refusing to save to a terminal. Use the -o flag or
- cowardly refusing to export to a terminal, specify a file pa
- requested load from stdin, but stdin is empty
- error: cannot perform an interactive login from a non-TTY de
- tty service logs only supported with --raw
AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01).
Data as JSON: /data/errors/c41bd4cddd26283a.json.
Report an issue: GitHub.