docker/compose · error

can't use --progress plain while ANSI support is forced

Error message

can't use --progress plain while ANSI support is forced

What it means

Docker Compose CLI rejects the combination `--progress plain` with `--ansi always`. The progress display mode 'plain' (no ANSI escape sequences) is logically incompatible with forcing ANSI output, so the mode selector in cmd/compose/compose.go aborts before configuring the display writer.

Source

Thrown at cmd/compose/compose.go:676

	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)
	}
}

func setEnvWithDotEnv(opts ProjectOptions, dockerCli command.Cli) error {
	// Check if we're using a remote config (OCI or Git)
	// If so, skip env loading as remote loaders haven't been initialized yet

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Drop `--ansi always` and let compose auto-detect ANSI support, keeping `--progress plain`.
  2. Or keep `--ansi always` and change `--progress` to `auto` or `tty`.
  3. Check for a shell alias or COMPOSE_ANSI environment variable forcing `always` when you did not pass it explicitly.

Example fix

# before
docker compose --ansi always --progress plain up --build

# after
docker compose --progress plain up --build
Defensive patterns

Strategy: validation

Validate before calling

# bash: check before invoking compose
ansi="${COMPOSE_ANSI:-auto}"; progress="plain"
if [ "$ansi" = "always" ] && [ "$progress" = "plain" ]; then
  echo "refusing: --progress plain conflicts with ansi=$ansi" >&2; exit 2
fi
docker compose --ansi "$ansi" --progress "$progress" up -d

Prevention

When it happens

Trigger: Running any compose command with both `--progress plain` and `--ansi always` (or the COMPOSE_PROGRESS/ansi env vars resolving to that combination). The switch on progress mode hits `case display.ModePlain` and sees the ansi setting == "always".

Common situations: CI scripts that pin `--ansi always` for colored logs and later add `--progress plain` to make build output greppable; shell aliases that set one flag and muscle-memory typing the other; env var COMPOSE_ANSI=always combined with a --progress plain flag.

Related errors


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