service "web" refers to undefined volume appdata: invalid compose project
— a service mounts a named volume, appdata:/data, and the Compose file has no
top-level volumes: section that declares appdata. Add the
declaration and the project starts.
The fix is three lines at the end of the file: volumes:, the volume's name
with a colon, and optionally a name: for the volume on the engine. Then run
docker compose up -d again.
The error
PS> docker compose up -d
service "web" refers to undefined volume appdata: invalid compose project
The command exited with code 1. docker compose config printed the same line
and exited with code 1 as well, so you can check a file without starting anything. The
file that produced it:
name: fix8-d3-vol
services:
web:
image: alpine
command: ["sleep", "5"]
volumes:
- appdata:/data
Why it happens
In a service's volumes list, the part before the colon can be a path such as
./appdata, a bind mount of a host folder, or a plain word such as
appdata, the key of a named volume. A named volume's key has to appear under
the top-level volumes: section of the same file. Here it does not, and
Compose rejected the project before it created a network, a volume or a container.
You meet this after copying one service out of a longer file, where the declaration stayed behind, or after a typo between the service's line and the declaration. The message names both the service and the missing key, so search the file for that key.
The fix
name: fix8-d3-vol
services:
web:
image: alpine
command: ["sleep", "5"]
volumes:
- appdata:/data
volumes:
appdata:
name: fix8-d3-appdata
PS> docker compose up -d
Volume fix8-d3-appdata Creating
...
Volume fix8-d3-appdata Created
...
Container fix8-d3-vol-web-1 Started
PS> docker compose ps --format '{{.Name}} {{.State}}'
fix8-d3-vol-web-1 running
The name: line is optional; it sets the volume's name on the engine. An empty
declaration, appdata: on its own line, also cleared the error; Compose then
created the volume as fix8-d3-vol2_appdata, the project name plus the key.
In these tests docker compose down -v removed the declared volume along with
the container and the default network, and plain docker compose down left
the volume in docker volume ls, which is what you want for data.
If you meant a host folder rather than a volume, write it as a path instead, for example
./appdata:/data; with that line and no top-level declaration,
docker compose config --quiet exited with code 0.
How it was reproduced
One alpine service running sleep 5 with
appdata:/data in its volumes list and no top-level
volumes: section, started with docker compose up -d from Windows
PowerShell 5.1 on Docker Engine 29.9.2 and Docker Compose v5.6.1 (Docker Desktop on
Windows 11). The project and volume names carry this test's fix8-d3- prefix.
The first project was removed with docker compose down -v; the
empty-declaration test was removed with docker compose down and
docker volume rm fix8-d3-vol2_appdata.
Frequently asked
- What does 'refers to undefined volume' mean in Docker Compose?
- A service mounts a named volume, such as appdata:/data, and the file has no top-level volumes section that declares that name. Compose rejects the project and starts nothing.
- How do I declare a named volume in docker-compose.yml?
- Add a top-level volumes: section at the end of the file with the volume's name followed by a colon, for example appdata:. A name: line under it is optional and sets the volume's name on the engine.
- Can I check a Compose file for this error without starting it?
- Yes. docker compose config printed the same 'refers to undefined volume' line and exited with code 1 in this test, without creating any container, network or volume.
More decoded errors in the Fixes category. When a volume will not go away later, see Docker: volume is in use.