docker/compose · error

can't use --progress tty while ANSI support is disabled

Error message

can't use --progress tty while ANSI support is disabled

What it means

The TTY progress renderer draws with ANSI escape sequences. If ANSI output is explicitly disabled (docker --ansi never / CLI ANSI=never env) while --progress tty is requested, the two settings conflict and compose refuses rather than emitting broken control codes to a non-ANSI terminal.

Source

Thrown at cmd/compose/compose.go:670

//
// In auto mode we probe Err() (not Out()) because the renderer writes to stderr;
// probing stdout would force plain mode whenever stdout is redirected (e.g.
// `docker compose up | tee log`) while stderr is still a terminal.
func selectEventProcessor(dockerCli command.Cli, progress, ansi string, detached bool) (api.EventProcessor, error) {
	switch progress {
	case "", display.ModeAuto:
		switch {
		case ansi == "never":
			display.Mode = display.ModePlain
			return display.Plain(dockerCli.Err()), nil
		case dockerCli.Err().IsTerminal():
			return display.Full(dockerCli.Err(), stdinfo(dockerCli), detached), nil
		default:
			return display.Plain(dockerCli.Err()), nil
		}
	case display.ModeTTY:
		if ansi == "never" {
			return nil, fmt.Errorf("can't use --progress tty while ANSI support is disabled")
		}
		display.Mode = display.ModeTTY
		return display.Full(dockerCli.Err(), stdinfo(dockerCli), detached), nil
	case display.ModePlain:
		if ansi == "always" {
			return nil, fmt.Errorf("can't use --progress plain while ANSI support is forced")
		}
		display.Mode = display.ModePlain
		return display.Plain(dockerCli.Err()), nil
	case display.ModeQuiet, "none":
		display.Mode = display.ModeQuiet
		return display.Quiet(), nil
	case display.ModeJSON:
		display.Mode = display.ModeJSON
		logrus.SetFormatter(&logrus.JSONFormatter{})
		return display.JSON(dockerCli.Err()), nil
	default:
		return nil, fmt.Errorf("unsupported --progress value %q", progress)

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Use `--progress auto` or `--progress plain` when ANSI is disabled
  2. Re-enable ANSI (drop `--ansi never` / unset the ANSI env) if your terminal does support it
  3. In CI, prefer `--progress plain` for parseable logs regardless of ANSI settings

Example fix

# before
docker --ansi never compose build --progress tty
# after
docker --ansi never compose build --progress plain
Defensive patterns

Strategy: validation

Validate before calling

# reconcile progress mode with ANSI setting before running
ansi="${DOCKER_CLI_ANSI:-auto}"
progress="${COMPOSE_PROGRESS:-auto}"
if [ "$ansi" = never ] && [ "$progress" = tty ]; then export COMPOSE_PROGRESS=plain; fi
docker compose build

Prevention

When it happens

Trigger: Running `docker --ansi never compose up --progress tty`, or having DOCKER_CLI_ANSI=never / running in an environment that disables ANSI, combined with --progress tty (or COMPOSE_PROGRESS=tty).

Common situations: CI systems that disable ANSI globally for clean logs but a script forces --progress tty; minimal terminals (plain serial consoles, some Windows shells) where ansi=never was set; copy-pasted commands mixing --ansi never and --progress tty.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/d93437bc6264456d. Report an issue: GitHub.