目录

Docker 常见错误消息大全:原因与解法(附实际输出)

这一页把 Docker 常见的错误消息整理在一起,标题就是错误消息的关键字,可以用浏览器的搜索功能(Ctrl+F)直接找。每个错误都附上在 Docker 29 实际重现的输出、原因与解法。

找不到你的错误时,排查的基本步骤是:

  1. 看错误消息最后一段的关键字。
  2. docker ps -a 看容器状态与退出码。
  3. docker logs 容器名称 看程序自己的输出。
  4. 详细的调试方法见 查看日志与调试。

连接与权限

failed to connect to the docker API / Cannot connect to the Docker daemon

$ docker run --rm --entrypoint docker docker:29.9-cli -H unix:///var/run/docker.sock ps
failed to connect to the docker API at unix:///var/run/docker.sock; check if the path is correct and if the daemon is running: dial unix /var/run/docker.sock: connect: no such file or directory

旧版的消息是 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?,意思相同:docker 命令(用户端)找不到 Docker Engine(服务器)。

解法:

  • Windows / macOS:确认 Docker Desktop 已经启动,系统匣的鲸鱼图标停止转动、状态是 Engine running。
  • Linux:启动 Docker 服务:sudo systemctl start docker,并设置开机启动:sudo systemctl enable docker。
  • 检查是否设置了 DOCKER_HOST 环境变量,或切换到了别的 context:docker context ls。

permission denied while trying to connect to the docker API

$ docker run --rm -u 1000:1000 -v /var/run/docker.sock:/var/run/docker.sock docker:29.9-cli docker ps
permission denied while trying to connect to the docker API at unix:///var/run/docker.sock

在 Linux 上,/var/run/docker.sock 只有 root 和 docker 群组可以访问。一般用户运行 docker 就会出现这个错误。

解法:把用户加入 docker 群组,然后重新登录(或运行 newgrp docker)才会生效:

sudo usermod -aG docker $USER

加入 docker 群组等同给予 root 权限,原因见 安全最佳实践。想避免的话可以使用 Rootless 模式。

端口与名称

port is already allocated

$ docker run -d --name web1 -p 8080:80 nginx:1.30-alpine
7a72d42f052dfebded509314b1975c72fbb1fcbf0c97099d6d60c9dedbcad8a1

$ docker run -d --name web2 -p 8080:80 nginx:1.30-alpine
6bcca59a67e5a5adbab1da7b2dbb7ef92f1df1f6e7680462a22541fd96f0ac9f
docker: Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint web2 (3a269ae1baae56a10b06552ba76fff69b3414885b2fa7a737344e081b4d5acd5): Bind for 0.0.0.0:8080 failed: port is already allocated

Run 'docker run --help' for more information

主机的 8080 已经被另一个容器使用(这里是 web1)。注意:错误发生时 web2 其实已经创建了,只是没有启动(状态是 Created),所以修正后直接再运行同一个命令,会遇到下一个错误「名称已被使用」。

解法:

  • 换一个主机端口:-p 8081:80。
  • 或停止占用的容器:docker ps 找出是谁在用 8080,然后 docker stop。
  • 删除创建失败的容器:docker rm web2。

address already in use

$ docker run -d --name web3 -p 9090:80 nginx:1.30-alpine
2c4649bbf85211d1ef6852c95fad52075b63d8d77e3fcd7c74db0bc7d15fbd8f
docker: Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint web3 (38386ef2562f999706b1d2b00eac0e48125eb006916dc857832ce18d36fe44d6): failed to bind host port 0.0.0.0:9090/tcp: address already in use

Run 'docker run --help' for more information

和上一个很像,但占用端口的是主机上的其他程序(不是容器),例如本机已经安装了 Nginx、MySQL,或开发服务器正在运行。

解法:找出占用的程序后关闭它,或换一个端口。

sudo lsof -i :9090          # Linux / macOS
netstat -ano | findstr 9090 # Windows

The container name "/web1" is already in use

$ docker run -d --name web1 -p 8081:80 nginx:1.30-alpine
docker: Error response from daemon: Conflict. The container name "/web1" is already in use by container "7a72d42f052dfebded509314b1975c72fbb1fcbf0c97099d6d60c9dedbcad8a1". You have to remove (or rename) that container to be able to reuse that name.

Run 'docker run --help' for more information

容器名称不能重复,包括已停止的容器。

解法:

  • 删除旧容器:docker rm -f web1。
  • 或换一个名称。
  • 一次性运行的容器加上 --rm,结束后自动删除,就不会留下同名容器。

镜像

not found / manifest unknown / pull access denied

$ docker pull nginx:9.99
Error response from daemon: failed to resolve reference "docker.io/library/nginx:9.99": docker.io/library/nginx:9.99: not found

$ docker pull ngnix-official-not-real
Using default tag: latest
Error response from daemon: failed to resolve reference "docker.io/library/ngnix-official-not-real:latest": docker.io/library/ngnix-official-not-real:latest: not found

找不到镜像。常见原因:

  • tag 打错或不存在:nginx:9.99 这个版本不存在。到 Docker Hub 的 Tags 页确认,或用 docker buildx imagetools inspect 镜像 查找。
  • 名称打错:ngnix。官方镜像名称没有前缀,例如 nginx、postgres。
  • 私有镜像没有登录:先 docker login。

依 Docker 版本与 Registry 的不同,同样的问题也可能显示为 manifest unknown 或 pull access denied for ..., repository does not exist or may require 'docker login'。

repository name must be lowercase / invalid reference format

$ docker build -t MyApp .
ERROR: failed to build: invalid tag "MyApp": repository name must be lowercase

镜像名称只能使用小写字母、数字和 -、_、.、/。把 MyApp 改成 myapp。名称中有空格、多了冒号(例如 myapp::1.0)时,则会出现 invalid reference format。

toomanyrequests: You have reached your pull rate limit

未登录时从 Docker Hub 下载镜像有次数限制,在短时间内大量拉取(例如 CI 每次都重新下载)就会遇到。这个错误没有在本教程环境重现,错误文本以官方说明为准。

解法:

  • docker login 登录 Docker Hub 账号,限制会放宽。
  • CI 中使用缓存,或改用其他 Registry 的镜像镜像。
  • 本机已经有的镜像不需要重新拉取,避免在命令中不必要地加 --pull always。

exec format error

镜像的 CPU 架构和主机不同,例如在 Apple Silicon Mac 上构建的 arm64 镜像放到 amd64 服务器上运行。实际输出与解法见 多平台镜像。

容器启动失败

exec /entrypoint.sh: no such file or directory(文件明明存在)

最常见于 Windows 用户:shell 脚本用 Windows 的换行(CRLF)存盘。

$ docker build -q -t crlf-demo .
sha256:194d0a73ff66c601a1e7b1bf80417ae47c5de6e5e076415f17b483e642929fc2

$ docker run --rm crlf-demo
exec /entrypoint.sh: no such file or directory

$ od -c entrypoint.sh | head -n 2
0000000   #   !   /   b   i   n   /   s   h  \r  \n   e   c   h   o    
0000020   "   h   e   l   l   o       f   r   o   m       e   n   t   r

od -c 显示第一行结尾是 \r \n。Linux 读到的解释器是 /bin/sh\r(多了一个看不见的 \r),这个程序当然不存在,所以出现 no such file or directory,非常误导人。

解法:

  • 在编辑器把换行改成 LF(VS Code 右下角点 CRLF 改成 LF)。

  • Git 在 Windows 上默认会把换行转成 CRLF,在项目根目录加入 .gitattributes,让脚本永远使用 LF:

    *.sh text eol=lf
  • 或在 Dockerfile 中转换:RUN sed -i 's/\r$//' /entrypoint.sh。

exec: "/entrypoint.sh": permission denied

$ docker build -q -t noexec-demo .
sha256:4f37fec89287104ccf6b509fef5c1836d2a1a65b36d858ff63b95fecc3340a0e

$ docker run --rm noexec-demo
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: exec: "/entrypoint.sh": permission denied

Run 'docker run --help' for more information

脚本没有运行权限。Windows 的文件系统没有 Linux 的运行权限,从 Windows 构建时特别容易遇到。

解法:在 Dockerfile 中加上运行权限:

COPY --chmod=755 entrypoint.sh /entrypoint.sh

或在 Linux / macOS 上 chmod +x entrypoint.sh 后再构建。

executable file not found in $PATH

$ docker run --rm alpine:3.23 bash
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: exec: "bash": executable file not found in $PATH

Run 'docker run --help' for more information

容器里没有这个程序。alpine 镜像没有 bash,只有 sh。

解法:改用 sh,或在 Dockerfile 中安装(RUN apk add --no-cache bash)。也常见于 CMD 写错程序名称、或程序没有被拷贝进镜像。

容器启动后马上 Exited (0)

$ docker run -d --name u1 ubuntu:26.04
9ff7034514a469602b48cc1bb3758514b32af8de6c602ce1bee11cd85813671c

$ docker ps -a --filter name=u1 --format "table {{.Names}}\t{{.Status}}"
NAMES     STATUS
u1        Exited (0) 2 seconds ago

$ docker rm u1
u1

这不是错误:容器在主进程结束时就会停止。ubuntu 镜像的默认命令是 bash,在后台运行(-d)且没有终端时,bash 读不到输入就结束了。

解法:

  • 想进去操作:docker run -it ubuntu:26.04 bash。
  • 想让它一直运行:给它一个不会结束的程序,例如网页服务器;测试用可以 sleep infinity。
  • 退出码不是 0 时,看 docker logs 找程序的错误消息。

Exited (137) 或 OOMKilled

退出码 137 表示容器被 SIGKILL 强制终止(128 + 9)。常见原因:

  • 内存不足:超过 --memory 限制或主机内存不足,被系统终止。用 docker inspect -f "{{.State.OOMKilled}}" 容器 确认,true 就是内存不足。
  • docker stop 等了 10 秒程序还没结束,被强制终止,原因见 Node.js 应用 的 PID 1 实测。
  • docker kill 或 docker rm -f。

本教程的测试主机没有激活 swap 限制,内存不足的情况无法稳定重现,所以这一项没有附上实际输出。

cannot attach stdin to a TTY-enabled container because stdin is not a terminal / the input device is not a TTY

$ docker run -d --name a1 alpine:3.23 sleep 300
55637ca715821720e55fa1366d8df8813915bf12b7520f65b9e85922ea7c475c

$ docker exec -it a1 bash
cannot attach stdin to a TTY-enabled container because stdin is not a terminal

-t 要求配置终端,但目前的输入不是终端。常见于:在脚本、CI、cron 中使用 docker exec -it,或用 <、| 把文件传给容器。

解法:非交互的情况拿掉 -t,只保留 -i(需要输入时)或什么都不加。例如还原数据库要用 docker exec -i。

构建(docker build)

failed to read dockerfile: open Dockerfile: no such file or directory

$ docker build -t x .
#0 building with "default" instance using docker driver

#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 2B done
#1 DONE 0.0s
ERROR: failed to build: failed to solve: failed to read dockerfile: open Dockerfile: no such file or directory

目前文件夹没有 Dockerfile。

解法:

  • 确认在正确的文件夹运行,最后的 . 是构建内容(build context)的路径。
  • 文件名必须是 Dockerfile(大小写一致,没有扩展名)。Windows 的记事本可能自动加上 .txt,文件名变成 Dockerfile.txt。
  • 文件名不同时用 -f 指定:docker build -f Dockerfile.dev .。

failed to calculate checksum ... not found(COPY 找不到文件)

$ docker build -t copy-demo .

[+] Building 0.1s (6/6) FINISHED                                                                                                       docker:default
 => [internal] load build definition from Dockerfile                                                                                             0.0s
 => => transferring dockerfile: 88B                                                                                                              0.0s
 => WARN: CopyIgnoredFile: Attempting to Copy file "config.json" that is excluded by .dockerignore (line 2)                                      0.0s
 => [internal] load metadata for docker.io/library/alpine:3.23                                                                                   0.0s
 => [internal] load .dockerignore                                                                                                                0.0s
 => => transferring context: 52B                                                                                                                 0.0s
 => [internal] load build context                                                                                                                0.0s
 => => transferring context: 2B                                                                                                                  0.0s
 => CACHED [1/2] FROM docker.io/library/alpine:3.23@sha256:85fe1e81d6758c208f3e1eed4338a1997e19d4be002d4dd32d3100c9a8c010a0                      0.0s
 => => resolve docker.io/library/alpine:3.23@sha256:85fe1e81d6758c208f3e1eed4338a1997e19d4be002d4dd32d3100c9a8c010a0                             0.0s
 => ERROR [2/2] COPY config.json /app/config.json                                                                                                0.0s
------
 > [2/2] COPY config.json /app/config.json:
------

 1 warning found (use docker --debug to expand):
 - CopyIgnoredFile: Attempting to Copy file "config.json" that is excluded by .dockerignore (line 2)
Dockerfile:2
--------------------
   1 |     FROM alpine:3.23
   2 | >>> COPY config.json /app/config.json
   3 |
--------------------
ERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref v1wocdfz4uxsgxp2q2kukkuqp::jww9anqv7tl0n3ksy
1tlwp8fv: "/config.json": not found

COPY 的文件不在构建内容中。最上面的 WARN: CopyIgnoredFile 已经说明了原因:config.json 被 .dockerignore 排除了。

常见原因:

  • 文件被 .dockerignore 排除(Docker 29 会先显示警告)。
  • 路径写错,或文件在构建内容(docker build 最后的 .)之外。COPY ../file 不能访问上层文件夹。
  • 大小写不一致:Windows 和 macOS 不分大小写,Linux 分。

RUN ... did not complete successfully: exit code: 1

构建时某个 RUN 命令失败。往上看 ------ 之间的输出,那是该命令自己的错误消息。例如 Python 应用 中 Django 的 collectstatic 因为没有设置 STATIC_ROOT 而失败。看不到完整输出时加上 --progress plain。

Volume、网络

volume is in use

$ docker volume create data
data

$ docker run -d --name holder -v data:/data alpine:3.23 sleep 300
38eb68e3f9c7020fdb86ded25f1e73dc0a9fdcb932dea1353d04c4474e0e50d7

$ docker volume rm data
Error response from daemon: remove data: volume is in use - [38eb68e3f9c7020fdb86ded25f1e73dc0a9fdcb932dea1353d04c4474e0e50d7]

$ docker rm -f holder
holder

$ docker volume rm data
data

Volume 还被容器使用(包括已停止的容器),不能删除。错误消息中的 ID 就是使用它的容器。先删除容器再删除 Volume。

network ... not found

$ docker run --rm --network appnet alpine:3.23 true
docker: Error response from daemon: failed to set up container networking: network appnet not found

Run 'docker run --help' for more information

指定的网络不存在。先 docker network create appnet 创建,或用 docker network ls 确认名称。Compose 项目的网络名称会加上项目名称前缀,例如 shop_default。

invalid mount config for type "bind": bind source path does not exist

用 --mount type=bind 挂载不存在的主机路径时会出现。实际输出与 -v 的差别见 Volume 与数据保存。

Docker Compose

yaml: ... did not find expected key / mapping values are not allowed

$ docker compose config
go-yaml load error in parser (while parsing a block mapping) at L3.C5-L6.C6: did not find expected key

YAML 的缩进错误。这个例子的 environment: 多缩进了一格。错误消息中的 L3.C5-L6.C6 表示从第 3 行第 5 栏到第 6 行第 6 栏之间的区块有问题。

解法:

  • 只用空白缩进,不要用 Tab。
  • 同一层的键要对齐。
  • 用 docker compose config 检查,没有错误时它会输出整理后的完整设置。

depends on undefined service

$ docker compose up -d
service "app" depends on undefined service "db": invalid compose project

depends_on 写了不存在的服务名称,通常是打错字,或服务被放进了 profiles 而没有激活。

The "DB_PASSWORD" variable is not set. Defaulting to a blank string.

$ docker compose config
time="2026-10-13T05:27:10Z" level=warning msg="The \"DB_PASSWORD\" variable is not set. Defaulting to a blank string."
name: c3
services:
  db:
    environment:
      POSTGRES_PASSWORD: ""
    image: postgres:18
    networks:
      default: null
networks:
  default:
    name: c3_default

这是警告而不是错误,但很危险:compose.yaml 用了 ${DB_PASSWORD},却没有在 .env 或环境变量中设置,于是被换成空字符串,数据库可能就用空密码初始化了。

解法:在 .env 中设置变量,或写成 ${DB_PASSWORD:?DB_PASSWORD is required},没有设置时直接报错停止,详见 环境变量与 .env 文件。

dependency failed to start: container ... is unhealthy

$ docker compose up -d
[+] up 3/3
 ✔ Network c4_default Created                                                                                                                     0.0s
 ✘ Container c4-db-1  Error dependency db failed to start                                                                                         2.8s
 ✔ Container c4-app-1 Created                                                                                                                     0.0s
dependency failed to start: container c4-db-1 is unhealthy

depends_on 设置了 condition: service_healthy,而依赖的服务健康检查一直失败。这个例子故意让健康检查运行 false。

排查:

  • docker inspect --format "{{json .State.Health}}" 容器 查看每次健康检查的输出。
  • 检查健康检查命令本身是否正确,例如密码、主机名称。数据库的健康检查写法见 MySQL 与 PostgreSQL。
  • 启动很慢的服务,加大 start_period 和 retries。

硬盘空间

No space left on device

$ docker run --rm --tmpfs /data:size=1m alpine:3.23 dd if=/dev/zero of=/data/big bs=1M count=2
dd: error writing '/data/big': No space left on device
2+0 records in
1+0 records out
1048576 bytes (1.0MB) copied, 0.001369 seconds, 730.5MB/s

写入的地方空间不足。这个例子用 1 MB 的 tmpfs 示范容器内的情况;实际上更常见的是主机上 Docker 的数据目录满了,构建或拉取镜像时出现同样的错误。

解法:

  • docker system df 看空间被什么占用,再依 清理硬盘空间 清理。
  • 检查容器日志是否太大,并设置日志上限。
  • Docker Desktop 可以在 Settings → Resources 调大虚拟磁盘上限。

Windows 特有的错误

以下用 PowerShell 7.4 实际运行(为了在同一个环境中实测,用 PowerShell 官方镜像在容器中运行 pwsh,所以命令前面多了 docker run ... pwsh -Command)。Windows PowerShell 5.1 的消息文本略有不同,但原因相同。

Variable reference is not valid. ':' was not followed by a valid variable name character

$ docker run --rm -e NO_COLOR=1 -w /home/me/project mcr.microsoft.com/powershell:latest pwsh -NoProfile -Command '$PSStyle.OutputRendering="PlainText"; mkdir /home/me/project -Force | Out-Null; Set-Location /home/me/project; Write-Output "$(pwd)/site:/app"; Write-Output "${PWD}/site:/app"'

/home/me/project/site:/app
/home/me/project/site:/app

$ docker run --rm -e NO_COLOR=1 -w /home/me/project mcr.microsoft.com/powershell:latest pwsh -NoProfile -Command '$PSStyle.OutputRendering="PlainText"; Write-Output "$PWD:/app"'
ParserError:
Line |
   1 |  $PSStyle.OutputRendering="PlainText"; Write-Output "$PWD:/app"
     |                                                      ~~~~~
     | Variable reference is not valid. ':' was not followed by a valid
     | variable name character. Consider using ${} to delimit the name.

在 PowerShell 中写 "$PWD:/app" 会出错:PowerShell 把 $PWD: 当成特殊的变量语法。改写成 "${PWD}:/app" 就正常。"$(pwd)/site:/app" 这种写法在 PowerShell 中也能用(第一个命令的两行输出相同)。

完整的 Windows 写法对照见 第一个容器。

The '<' operator is reserved for future use

$ docker run --rm -e NO_COLOR=1 -w /home/me/project mcr.microsoft.com/powershell:latest pwsh -NoProfile -Command '$PSStyle.OutputRendering="PlainText"; docker exec -i mysql mysql app < app.sql'
ParserError:
Line |
   1 |  … OutputRendering="PlainText"; docker exec -i mysql mysql app < app.sql
     |                                                                ~
     | The '<' operator is reserved for future use.

PowerShell 不支持 < 把文件导入命令,所以教程中还原数据库的 docker exec -i ... < backup.sql 在 PowerShell 中无法运行。

解法:先用 docker cp 把文件拷贝进容器,再在容器内导入。这个方法在所有系统都通用,也避开了 PowerShell 5.1 的 > 会把文件存成 UTF-16 编码的问题。以 PostgreSQL 为例:

$ docker compose exec db psql -U app -c 'CREATE TABLE t (id int); INSERT INTO t VALUES (1),(2);'
CREATE TABLE
INSERT 0 2

$ docker compose exec db pg_dump -U app -Fc -f /tmp/app.dump app

$ docker compose cp db:/tmp/app.dump app.dump
 pgwin-db-1 Copying pgwin-db-1:/tmp/app.dump to app.dump
 pgwin-db-1 Copied pgwin-db-1:/tmp/app.dump to app.dump

$ ls -l app.dump
-rw-rw-rw-    1 root     root          1251 Oct 13 05:30 app.dump

$ docker compose exec db psql -U app -c 'DROP TABLE t;'
DROP TABLE

$ docker compose cp app.dump db:/tmp/restore.dump
 pgwin-db-1 Copying app.dump to pgwin-db-1:/tmp/restore.dump
 pgwin-db-1 Copied app.dump to pgwin-db-1:/tmp/restore.dump

$ docker compose exec db pg_restore -U app -d app /tmp/restore.dump

$ docker compose exec db psql -U app -c 'SELECT count(*) FROM t;'
 count
-------
     2
(1 row)

MySQL 的写法见 MySQL 的备份一节。

重点回顾

  • 先看错误消息最后一段的关键字,再用 docker ps -a、docker logs 确认状态。
  • 端口被占用、名称冲突时,失败的容器可能已经创建,记得 docker rm。
  • Windows 上的脚本要用 LF 换行并有运行权限,否则会出现误导人的 no such file or directory 或 permission denied。
  • Compose 的问题先跑 docker compose config。
  • PowerShell 中用 ${PWD},并避免使用 < 导入文件。

常见问题

错误消息很长,应该看哪一段?

先看最后一段冒号后面的文本,那通常才是真正的原因,例如 port is already allocated、no such file or directory。前面的 Error response from daemon、failed to create task 只是说明错误发生在哪一层。

为什么网络上搜到的错误消息和我看到的不一样?

Docker 各版本的错误消息会改写。例如旧版的 Cannot connect to the Docker daemon at unix:///var/run/docker.sock 在 Docker 29 变成 failed to connect to the docker API at unix:///var/run/docker.sock。用最后的关键字搜索比较容易找到答案。

docker run 失败后,为什么再运行一次会出现名称已被使用?

很多错误(例如端口被占用)发生时,容器其实已经创建了,只是没有启动成功。用 docker ps -a 看得到它,处于 Created 状态。先 docker rm 删除它再重新运行。

怎么看容器为什么退出?

依序运行 docker ps -a 看 STATUS 中的退出码、docker logs 容器名称 看程序输出,以及 docker inspect -f "{{.State.ExitCode}} {{.State.OOMKilled}}" 容器名称。退出码 137 表示被强制终止(SIGKILL 或内存不足),1 通常是程序本身出错。

更新于 2026年10月13日