invalid interpolation format for services.web.environment.DB_PASSWORD. You may need to escape any $ with another $. — a value in the Compose file contains a $ that Compose tries to read as a variable, and the text after it is not a valid variable reference. Write the dollar sign twice, $$, and Compose passes a single $ to the container.

The message names the exact key, here services.web.environment.DB_PASSWORD, and prints the value on its last line. Double every $ in that value that is meant literally, then run the command again.

The error

PS> docker compose up -d
invalid interpolation format for services.web.environment.DB_PASSWORD.
You may need to escape any $ with another $.
pa${word-not-real

The command exited with code 1, and docker compose config printed the same three lines with the same exit code. The file, with an obviously fake password:

name: fix9-cmp-c7
services:
  web:
    image: alpine
    command: ["sleep", "300"]
    environment:
      DB_PASSWORD: "pa${word-not-real"

Why it happens

Compose reads a $ in a value as the start of a variable reference, written $NAME or ${NAME}, and fills it in from the environment. Here the value holds ${ with no closing brace, which cannot be read as a reference, so Compose stopped with this message instead of guessing. Quoting the value in YAML did not help: the double quotes are YAML's, and the $ inside them was still read by Compose.

A $ followed by a plain word is worse, because it does not fail. With "pa$word-not-real" in the same place, up printed The "word" variable is not set. Defaulting to a blank string. as a warning, exited with code 0, and the container received a different password:

PS> docker compose exec web printenv DB_PASSWORD
...
pa-not-real

The fix

    environment:
      DB_PASSWORD: "pa$${word-not-real"
PS> docker compose config
...
    environment:
      DB_PASSWORD: pa$${word-not-real
...
PS> docker compose up -d
...
 Container fix9-cmp-c7-web-1 Started
PS> docker compose exec web printenv DB_PASSWORD
pa${word-not-real

Note what each command showed: docker compose config printed the value still escaped, with $$, while printenv inside the container printed the password as intended, with one $. Check the value in the container, not in the config output, and double every literal $ in the value, not only the one the message points at: the single-dollar test above shows that a $ before a word passes the check and still changes the value.

How it was reproduced

One alpine service running sleep 300 with a DB_PASSWORD environment entry holding a fake value, tried as pa${word-not-real, pa$${word-not-real and pa$word-not-real, with docker compose up -d, docker compose config and docker compose exec web printenv DB_PASSWORD, from Windows PowerShell 5.1 on Docker Engine 29.9.3 and Docker Compose v5.7.0 (Docker Desktop on Windows 11). The project name carries this test's fix9-cmp- prefix and was removed with docker compose down -v.

Frequently asked

How do I escape a dollar sign in docker-compose.yml?
Write it twice, $$. In this test pa$${word-not-real in the file reached the container as pa${word-not-real.
What does 'invalid interpolation format' mean in Docker Compose?
A value contains a $ that cannot be read as a variable reference, here ${ with no closing brace. The message names the key and prints the value, and up and config both exit with code 1.
Why does my password with a dollar sign arrive cut short in the container?
A $ followed by a word is read as a variable. In this test pa$word-not-real reached the container as pa-not-real, with only a 'variable is not set' warning. Escape it as $$.

More decoded errors in the Fixes category. For the warning a single $ before a word produces, see Docker Compose: variable is not set, defaulting to a blank string.