Skip to content
Latchkey

Docker Compose "the attribute version is obsolete" (warning to error) in CI

Compose v2 ignores the top-level version: key and prints a deprecation warning. Most pipelines tolerate the warning, but CI that fails on any stderr output (or a lint gate) turns it into a build failure. Removing the obsolete key clears it.

What this error means

A docker compose command prints the attribute "version" is obsolete, it will be ignored, please remove it to avoid potential confusion and the step fails because stderr is treated as an error.

docker
WARN[0000] /app/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion

Diagnose it: read the resolved config, not the file you wrote

Compose merges override files, interpolates variables, and applies defaults before it does anything. Most Compose failures in CI are visible in the resolved configuration and invisible in the source file, because the value you are debugging came from an unset variable that quietly became an empty string.

Terminal
# the fully merged, interpolated configuration Compose will actually run
docker compose config

# fail loudly on unset variables instead of silently interpolating empty
docker compose --env-file .env config --quiet || echo "invalid"

# which override files were picked up
docker compose config --services

Common causes

A leftover top-level version key

Compose v2 no longer uses version:; its presence triggers the deprecation warning.

A strict CI gate failing on warnings

A step that fails on any stderr output (or a --quiet/lint check) escalates the warning to an error.

How to fix it

Remove the version key

  1. Delete the top-level version: line from the compose file.
docker-compose.yml
# remove this line:
# version: "3.8"
services:
  web:
    image: myorg/app:ci

Stop treating the deprecation warning as fatal

  1. If you must keep the key, ensure the CI step does not fail on benign stderr output.
Terminal
docker compose config --quiet

Bind mounts behave differently on a runner

  • A relative bind source is resolved against the compose file location, not the working directory of the shell that invoked it.
  • The host path must exist before up. Compose creates missing directories for named volumes but not for bind mounts, and the failure surfaces as a mount error rather than a missing-path error.
  • On a CI runner the workspace path differs from your machine, so any absolute host path in a compose file is a portability bug waiting for its first CI run.
  • Prefer named volumes for anything that does not genuinely need to be read from the host. They remove the whole class of problem.

How to prevent it

  • Drop the top-level version: key on Compose v2.
  • Reserve hard-fail-on-stderr gates for real errors, not deprecation notices.

Frequently asked questions

What causes Docker Compose "the attribute version is obsolete" (warning to error) in CI?
There are 2 common causes: a leftover top-level version key and a strict ci gate failing on warnings. Compose v2 no longer uses version:; its presence triggers the deprecation warning.
How do I fix Docker Compose "the attribute version is obsolete" (warning to error) in CI?
There are 2 fixes depending on which cause you have: remove the version key and stop treating the deprecation warning as fatal. Work through them in order, since the first is the most common.
What does Docker Compose "the attribute version is obsolete" (warning to error) in CI actually mean?
A docker compose command prints the attribute "version" is obsolete, it will be ignored, please remove it to avoid potential confusion and the step fails because stderr is treated as an error.
How do I stop Docker Compose "the attribute version is obsolete" (warning to error) in CI happening again?
Drop the top-level version: key on Compose v2. The prevention section lists 2 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card