docker/compose · error

--wait cannot be combined with --abort-on-container-exit, --

Error message

--wait cannot be combined with --abort-on-container-exit, --attach or --attach-dependencies

What it means

Returned by validateFlags when --wait is combined with any attach-mode flag: --attach-dependencies, --abort-on-container-exit (cascadeStop, including the implicit set from --exit-code-from), or explicit --attach SERVICE. --wait implies detached mode plus its own health-based readiness monitoring, which conflicts with streaming logs / aborting on container exit.

Source

Thrown at cmd/compose/up.go:202

		return pflag.NormalizedName(name)
	})
	return upCmd
}

//nolint:gocyclo
func validateFlags(up *upOptions, create *createOptions) error {
	if up.waitTimeout < 0 {
		return fmt.Errorf("--wait-timeout must be a non-negative integer")
	}
	if up.exitCodeFrom != "" && !up.cascadeFail {
		up.cascadeStop = true
	}
	if up.cascadeStop && up.cascadeFail {
		return fmt.Errorf("--abort-on-container-failure cannot be combined with --abort-on-container-exit")
	}
	if up.wait {
		if up.attachDependencies || up.cascadeStop || len(up.attach) > 0 {
			return fmt.Errorf("--wait cannot be combined with --abort-on-container-exit, --attach or --attach-dependencies")
		}
		up.Detach = true
	}
	if create.Build && create.noBuild {
		return fmt.Errorf("--build and --no-build are incompatible")
	}
	if up.Detach && (up.attachDependencies || up.cascadeStop || up.cascadeFail || len(up.attach) > 0 || up.watch) {
		if up.wait {
			return fmt.Errorf("--wait cannot be combined with --abort-on-container-exit, --abort-on-container-failure, --attach, --attach-dependencies or --watch")
		} else {
			return fmt.Errorf("--detach cannot be combined with --abort-on-container-exit, --abort-on-container-failure, --attach, --attach-dependencies or --watch")
		}
	}
	if create.noInherit && create.noRecreate {
		return fmt.Errorf("--no-recreate and --renew-anon-volumes are incompatible")
	}
	if create.forceRecreate && create.noRecreate {
		return fmt.Errorf("--force-recreate and --no-recreate are incompatible")

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Pick one model: for health-based readiness use `up --wait --wait-timeout N` and drop attach/abort flags.
  2. To follow logs instead, drop --wait and use `up -d && docker compose logs -f web`.
  3. Replace `--wait --exit-code-from web` with `--wait && docker compose exit-code` style flows or --abort-on-container-failure alone.

Example fix

# before
docker compose up --wait --attach web

# after
docker compose up --wait
docker compose logs -f web &
Defensive patterns

Strategy: validation

Validate before calling

case " $* " in
  *' --wait '*)
    for f in --attach-dependencies --abort-on-container-exit --exit-code-from; do
      [[ " $* " == *" $f"* ]] && { echo "--wait cannot combine with $f" >&2; exit 2; }
    done;;
esac
docker compose up "$@"

Prevention

When it happens

Trigger: `docker compose up --wait --attach web`; `up --wait --attach-dependencies`; `up --wait --abort-on-container-exit`; `up --wait --exit-code-from web` (exit-code-from sets cascadeStop). The check fires only when cascadeStop came from the explicit flag path, not when --wait itself enabled it.

Common situations: CI wanting both 'wait until healthy' and 'stream this one service's logs'; teams copying a long flag line and appending --wait; confusion between --wait (healthcheck-based) and attach-based readiness.

Related errors


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