I shared this post on the official Docker forum as well, in case you prefer reading there. I will try to keep these posts in sync, but leave a comment if you think theye are not.
Introduction
There is a common error message that Docker users get
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
Sometimes you get an IP address
Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running?
Or sometimes a default domain:
Cannot connect to the Docker daemon at http://docker.example.com. Is the docker daemon running?
Although the solution is often quite simple, people often jump to the wrong conclusion that the Docker client knows exactly whether the daemon is running or not, and they don't understand what else could be the problem, when they see the Docker daemon running. So in this post I will explain what the error message is, what it isn't, and how can a single error message mean so many things. Of course, I will also share the solutions I know about, but what I want you to learn here is how to understand the error message in the context of your environment and the way to find a solution for your case.
Table of contents
- The meaning of the error message
- Quick guide for the impatient
- Problems and solutions in details
- I got "is the Docker daemon running", but I followed the official installation guide
The meaning of the error message
Notice that it is a question at the end and not a statement. So it is either the dockerd process is not running or the client could not tell whether it is running or not. The Docker client will not check the running processes on the host machine. The client could run on your workstation while you are trying to connect to a Docker daemon running on a remote machine or in a virtual machine, maybe even created by Docker Desktop. So the client will attempt to connect to the daemon, and if it fails to do so, the client will tell you that one possible reason of failing is that the daemon is not even running.
The second detail you need to notice is the unix socket in the error message. That is a file on the filesystem of the machine on which the client is running, but it is almost always the same as the one on which the daemon is running, or at least the same physical machine while the daemon is running in a VM (like Docker Desktop). In case there is only one machine, this is the file used by both, the client and the daemon, so the client can communicate with the Docker daemon. This file is not a regular file, just a way for processes to communicate with each other through the kernel memory. Fortunately, you don't have to know anything about that, but this is probably the reason why you can't mount this socket file (or any other unix domain socket) into a virtual machine.
Oh... you think you could do that with Docker Desktop? No, you couldn't, but there is a Docker socket inside the VM as well. So when you mount the docker socket into a container, you mount the one from the virtual machine.
Even though this file is not a regular file, you can still set permissions on the file, which means you can allow or deny access to the file for different users. If you don't have access to the unix domain socket which is configured for the client, it will not be able to use it for communication. It will not be able to connect to the Docker daemon, even if the daemon is running and listening on this socket for requests. Note that unix://
is just a protocol similarly to http://
. The difference is that after an HTTP protocol, the next part is the domain name or IP address, while the next part after the unix domain socket protocol is the file path, which starts with a slash character on Linux. That is why you see 3 slashes. One is part of the filepath, the other two are part of the protocol reference.
Quick guide for the impatient
Here is a summary of what you should consider:
- There are multiple Docker variants, and knowing which one you are using can help you find out whether it is running or not, because you know where to look for the process. On the other hand, if you know, how you can list processes on the operating system, and look for the Docker daemon in the list, that can help you to figure out which Docker variant you have. Be careful, because you could have more than one.
- Are you using a remote daemon running on a remote server, or a local daemon
- Does the socket file exist?
- Does the Docker client has access to the file?
- If you have access to the file, are you sure that this socket is the one that is used by the Docker daemon?
Problems and solutions in details
Find out which Docker variant you have
First you need to know which Docker variant you have. People often install Docker CE and Docker Desktop when they only want to have the Desktop. Then they actually try to connect to the wrong daemon. I wrote about the different kind of Docker installations in "You run containers, not dockers - Discussing Docker variants, components and versioning". If you want to learn more about it in practice, you can also read "Which Docker variant am I using and where is the daemon running?"
Docker runtime contexts
We have to talk about docker contexts. If I'm not specific enough, it could be confused with the docker build contexts which is a completely different topic. What I'm talking about now is what we could call the "Docker runtime context". The context definition that tells the client how to connect to the daemon on the server where the containers will run. The following command can show you the current contexts:
docker context ls
Sometimes the easiest solution is switching to another context or create one first if none of the existing contexts are correct. If you don't want to create a context, you can also set an environment variable temporarily to change the host. It is mentioned in the linked documentation, but there is another one with an example: Protect the Docker daemon socket / Secure by default. I will also use this later in this post.
If you want to get the actual endpoint from the current context, you can also run
docker context inspect --format '{{ .Endpoints.docker.Host }}'
Which can show you something like unix:///var/run/docker.sock
.
Running remote Docker daemons
Even if you are using Docker CE, the Docker client can connect to a remote server. If you know that the daemon is running on a remote server, because you have a VPS to which you want to connect using SSH, you could get a slightly different error from what I shared in the intro.
Cannot connect to the Docker daemon at http://docker.example.com. Is the docker daemon running?
It is still the same kind of error, but there is an HTTP endpoint instead of the unix socket. This is special, since even when you don't have a unix domain socket on Linux, you have a TCP socket, not HTTP. When you try to actually use URL as an endpoint, you will get "invalid bind address format".
DOCKER_HOST="http://docker.example.com" docker ps
output:
Failed to initialize: unable to resolve docker endpoint: invalid bind address format: http://docker.example.com
This is still currently the default at the time of writing this post when the unix socket cannot be found through the SSH connection. You can reproduce it with the following command, assuming the hostname to your VPS is myvps
.
DOCKER_HOST="ssh://myvps/var/run/docke.sock" docker ps
In the above command I intentionally set a wrong socket path using an SSH connection, but I can try TCP as well.
DOCKER_HOST="tcp://127.0.0.1" docker ps
Then we get the IP address in the error message, not the default domain
Cannot connect to the Docker daemon at tcp://127.0.0.1:2375. Is the docker daemon running?
And if you try a domain name, you see the domain name in the error message, except when the domain name cannot be resolved to an IP address, in which case you have a DNS issue with a completely different error message.
DOCKER_HOST="tcp://myvips" docker ps
Output
error during connect: Get "http://myvips:2375/v1.47/containers/json": dial tcp: lookup myvips: no such host
This is out of the scope of this post, but I still have to mention that the environment variable is not the only way to get this error. You could have a Docker runtime context as well.
Check if the Docker daemon is actually running
First of all, the "Find out which Docker variant you have" section could already help you, because knowing which Docker variant you had also required being able to check the running processes, but there is more.
Docker CE status on Linux running under Systemd
If you followed the official documentation to install Docker CE, the Docker daemon is running under systemd. In that case the following command should tell you if it is running or not.
sudo systemctl status docker
It actually works for non-official packages if Systemd was used to run the daemon. Since most of the Linux distributions today use Systemd, it usually works. On older Windows Subsystem for Linux versions, Systemd was not available, so you had to run a different command:
sudo service docker status
This actually works even if you have systemd, since the service
script can recognize it and use systemctl commands behind the scenes.
The output would be something like this:
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
Active: active (running) since Wed 2025-01-01 17:32:24 CET; 3 days ago
This is only the beginning the output, but the important part is "Active: active (running)
". Depending on your terminal configuration, the circle next to the service name could be green when the service is running.
If you have Rootless Docker, the daemon is running as your non-root user, and the systemctl command is different:
systemctl --user status docker
notice that there is no sudo
in the command and we use the --user
flag.
Docker as a Snap package status
If you installed Docker as a Snap package, the following command will list the running services
snap services
Output:
Service Startup Current Notes
docker.dockerd enabled active -
docker.nvidia-container-toolkit enabled inactive -
The only service I have in this example is the Docker daemon and the Nvidia Container Toolkit which is inactive. The "dockerd.dockerd" service is active, so it is running. If you have many Snap services, you can of course get the status of one service directly:
snap services docker.dockerd
Output
Service Startup Current Notes
docker.dockerd enabled active
Docker CE status in Docker Desktop
If you have Docker Desktop, the Docker daemon is running in a virtual machine. If the host operating system is Linux, there is a systemctl command that shows the status of the docker-desktop
service.
systemctl --user status docker-desktop
This is again the status of Docker Desktop, and not the daemon which is running in the virtual machine of Docker Desktop. If you want to know the status of the engine, open the GUI of Docker Desktop and look for the "Engine running" message currently in the bottom left corner of the window.
Check if the Docker unix domain socket exists
It is usually at /var/run/docker.sock
, but it can be changed, so just look for what the error message says, or run the command I already mentioned before:
docker context inspect --format '{{ .Endpoints.docker.Host }}'
If it is a unix domain socket file, you should be able to check it by running the following command in which I will assume the path is the default:
file /var/run/docker.sock
The output:
/var/run/docker.sock: socket
It also tells you if the file is an actual socket. If not, you have to fix the socket.
Check if you have permission to the socket
Maybe it is an existing socket, but you don't have permission to access it. The following command can reveal that:
ls -l /var/run/docker.sock
Output:
srw-rw---- 1 root docker 0 Jan 3 12:49 /var/run/docker.sock
It shows that the socket is owned by root, and it is assigned to the "docker" group. rw-rw----
means that only the owner (root) or a user in the group (docker) can read and write the file. so you are either using
sudo docker ps
to list containers, or you add your user to the Docker group:
sudo usermod -aG docker USERNAME
There is actually a third option that I sort of "invented", since I have never seen this anywhere else, but you can read about it in "Allow non-root users to use the docker commands".
Make sure you are using the right socket
As I already pointed out, some users install Docker CE when they actually want to use Docker Desktop, but when the documentation says that adding the official package repository to the system is required, and it links to the configuration guide, they continue with the rest of the steps, which are not just not required, but also not recommended. The only package you need from the official repository is the Docker Client which is called "docker-ce-cli
", and which will install "docker-buildx-plugin
" and "docker-compose-plugin
" as well.
If you install "docker-ce
", you will have a second daemon outside of Docker Desktop, and when Docker Desktop is running, it changes the runtime context to "desktop-linux", so even if you checked the context previously, it will be changed, and you connect to another socket. This is one more time when docker context
commands could be useful to see which context you are in, but know that when you use the docker commands with sudo
, you will run the docker client as root, which has no configured access to your Docker Desktop socket in your home directory, and you connect to the daemon of Docker CE on the host, not Docker Desktop. So even if the socket you check is accessible by your user, it is possible that it is not the one you wanted to use, and you can get an error message when trying to connect to the wrong daemon.
If you have Rootless Docker, it is a similar situation, since it has a different socket too, and it is configured only for your non-root user, so using sudo would result in using another daemon.
Don't forget to check the endpoint in the context using
docker context ls
or
docker context inspect --format '{{ .Endpoints.docker.Host }}'
and find out if this is the right context. It is also possible that something added an environment variable to your shell. Run
echo "$DOCKER_HOST"
to find out if this is the case, figure out where it was set (possibly in your .bashrc
file in your home) and remove it or change it. This could happen also when you are running Docker in a CI/CD pipeline, although in that case it is not likely to be wrong. You should still check it to make sure.
If you have multiple Docker installation on the same machine, or you changed the daemon configuration or used a non-official installer for the daemon part, it is possible that the socket in the error message is not the one that the daemon is using, so you need to reconfigure the client either by setting a docker runtime context or the environment variable.
I got "is the docker daemon running", but I followed the official installation guide
We had multiple cases on the Docker forum when the user stated they followed the official documentation for example on Ubuntu, and they still got the error message.
The problem is that people often ignore the "Next steps" section, which is this:
Continue to Post-installation steps for Linux
This is where the group membership is set. Even if you didn't ignore it and configured the user properly, it can be that you have one of the previously mentioned issues due to multiple Docker daemons on your system.
Conclusion
By this time you could learn that the error message is not a statement, but a question or an assumption. There is a general form of this error message, but the endpoint can be multiple thing. I hope I could help you to understand the meaning of all, so you can make your Docker work again.
You could learn some of the risks of running multiple Docker daemons on the same machine, but there are other risks not included here, since those are not related to the discussed error messages.
As always I tried to include all the related problems and solutions that I know of, but obviously I can't always think of everything. If you are sure, that you have none of the issues mentioned in this post, leave a comment here or on the official Docker forums to figure out what happened to your system. Please, share what you have actually tried, and not just that you tried everything mentioned in this or any other post, since it could be easy to miss something!
Top comments (0)