Fix 'bind source path does not exist' Error When Mounting Volumes in Docker

beginner๐Ÿณ Docker2026-03-18| Docker Engine 20+, Docker Compose v2, Linux / macOS / Windows (WSL2)

Error Message

Error response from daemon: invalid mount config for type "bind": bind source path does not exist
#docker#volume#bind-mount#docker-compose

TL;DR

Docker can't mount a directory that doesn't exist yet. Create it first, then re-run your container:

mkdir -p /path/to/your/host/directory
docker run -v /path/to/your/host/directory:/container/path your-image

For Docker Compose, either create the folder manually before running docker compose up, or switch to a named volume and let Docker handle it.

What Triggers This Error

The full error reads:

Error response from daemon: invalid mount config for type "bind": bind source path does not exist

Bind mounts work by linking a host directory directly into the container filesystem. Docker doesn't create that directory for you โ€” it must already exist. Named volumes are different; Docker manages those automatically. Bind mounts? You're responsible for the source path.

Common culprits:

  • Typo in the host path (e.g., /dat/myapp instead of /data/myapp)
  • Path is relative to the wrong working directory
  • Directory was deleted or never created in the first place
  • On Windows/WSL2: mixing Windows and Unix path formats
  • Docker Compose volumes block points to a host path that doesn't exist

Fix 1: Create the Missing Host Directory

Nine times out of ten, this is all you need. Find the path in your -v flag and create it:

# Your failing command
docker run -v /data/myapp/config:/app/config myimage

# Create the missing directory
mkdir -p /data/myapp/config

# Run again โ€” should work now
docker run -v /data/myapp/config:/app/config myimage

The -p flag tells mkdir to create all parent directories in one shot. No need to create /data then /data/myapp separately.

Fix 2: Check for Typos First

Worth doing before you create anything new โ€” the path might already exist, just misspelled:

# Does it exist?
ls -la /data/myapp/config

# One-liner check
[ -d /data/myapp/config ] && echo "exists" || echo "missing"

One wrong character is enough. /data/myapp and /dat/myapp are completely different paths. Check every segment.

Fix 3: Docker Compose โ€” Relative Paths and Named Volumes

This catches a lot of people. Take this docker-compose.yml:

services:
  app:
    image: myimage
    volumes:
      - ./config:/app/config

That ./config resolves relative to wherever your docker-compose.yml lives. If the config folder isn't there, Docker bails immediately. The fix is simple:

# Run this from the same directory as docker-compose.yml
mkdir -p config
docker compose up -d

Don't actually need files in that directory beforehand? Switch to a named volume instead:

services:
  app:
    image: myimage
    volumes:
      - app-config:/app/config

volumes:
  app-config:

Docker creates named volumes automatically on first run. Use bind mounts when you need to read or write files directly from the host โ€” config files, build artifacts, logs you want to tail in real time.

Fix 4: Windows and WSL2 Path Formats

Docker Desktop on Windows is picky about path format. Use the wrong style for your terminal and you'll get this error every time.

From PowerShell or CMD:

# Wrong โ€” Unix-style path won't resolve
docker run -v /c/Users/you/data:/app/data myimage

# Correct โ€” Windows backslashes
docker run -v C:\Users\you\data:/app/data myimage

# Also correct โ€” forward slashes work too
docker run -v C:/Users/you/data:/app/data myimage

From a WSL2 terminal, stick to Linux paths:

# Native WSL2 path
docker run -v /home/you/data:/app/data myimage

# Accessing your Windows C: drive from WSL
docker run -v /mnt/c/Users/you/data:/app/data myimage

The rule: match the path style to the shell you're running from.

Fix 5: Empty Environment Variables

Variables that look set but aren't will silently produce a broken path:

# If $DATA_DIR is unset, this becomes -v :/app/data โ€” instant error
docker run -v $DATA_DIR:/app/data myimage

# Debug first
echo "DATA_DIR=${DATA_DIR}"

# Add a fallback so it never expands to nothing
docker run -v ${DATA_DIR:-/tmp/myapp-data}:/app/data myimage

An unset variable expands to an empty string. Docker sees -v :/app/data, which points nowhere.

Verify the Fix

Container running? Double-check the mount actually landed correctly:

# Start a named container
docker run -d --name test-bind -v /data/myapp/config:/app/config myimage

# Confirm it's up
docker ps | grep test-bind

# Inspect the mount details
docker inspect test-bind --format '{{ json .Mounts }}' | python3 -m json.tool

Look for "Type": "bind" in the output, with your expected source and destination paths. If those are correct, you're done.

For Compose stacks:

docker compose up -d
docker compose ps
docker compose exec app ls /app/config

Quick Reference

  • Named volume โ€” Docker creates and manages it; no host path required
  • Bind mount โ€” Host path must exist before the container starts
  • tmpfs mount โ€” Lives in memory only; gone when the container stops

Running this in CI/CD? Add a directory setup step before your Docker commands:

mkdir -p ./data ./logs ./config
docker compose up -d

Three seconds of prep, zero bind mount errors.

Related Error Notes