Fix Docker Daemon Configuration Errors in CI
Resumen
Pixel shares a guide to diagnosing Docker daemon startup failures in CI, including invalid daemon.json syntax and options duplicated between the config file and systemd flags. It explains why container jobs fail when the daemon never starts and highlights checking system journal logs for the actual error.
DEV Community
Unable to configure the Docker daemon with file daemon.json in CI
Unable to configure the Docker daemon with file daemon.json is dockerd refusing to start because it could not turn your configuration file into a usable configuration. The sentence is only a wrapper: what actually went wrong is in the clause that follows the file name, and it is either the file failing to parse or an option being set in two places at once. Flags and the file are merged before anything starts. A parse failure and a duplicate directive both stop it there. What this error means Every Docker command in the job fails to connect, and the reason is not in the job log at all, because the daemon never came up to write one. On a runner you provision yourself, this typically follows a provisioning step that wrote /etc/docker/daemon.json for a registry mirror, a log driver or a storage option, and the workflow that used to work now fails at its first container. The daemon logs the real line to the system journal, so the failure is invisible until you go and look there. ```The line docker/for-linux#327 reports from dockerd (quoted, not a recorded run) unable to configure the Docker daemon with file /etc/docker/daemon.json: the following directives are specified both as a flag and in the configuration file: insecure-registries: (from flag: [192.168.0.2:5000], from file: [192.168.0.2:5000])
Common causes
The file is not valid JSON
A trailing comma, an unquoted key, a smart quote pasted from a document, or a stray brace. The Go decoder reports the character and what it expected, which is enough to find the spot, and the daemon refuses to start rather than guessing at what you meant.
An option is set both as a flag and in the file
The daemon checks for this deliberately and aborts rather than picking a winner. The classic is a registry or host setting present in a systemd unit override and in daemon.json at the same time, usually because two different guides were followed months apart.
A key is misspelled or not supported by this version
Configuration keys change between Docker releases, and a key copied from a newer version of the documentation onto an older daemon is rejected at startup. In our experience this is the cause when the file is obviously valid JSON and the message still names the file rather than a parse position.
A provisioning step appended to the file with text tools
Shell redirection that adds a key to an existing JSON object produces a file that looks right and is not. This is the mechanism behind most of the parse failures above, and it is worth naming separately because the fix is to change how the file is written, not just to repair it once.
How to fix it
Validate the file in the step that writes it
- Parse the file with a real JSON parser immediately after writing it.
- Fail the provisioning step on a parse error, before anything restarts the daemon.
- Only then restart Docker, and check the unit actually came back up.
```Terminal
sudo tee /etc/docker/daemon.json >/dev/null <<'JSON'
{ "registry-mirrors": ["https://mirror.example.internal"] }
JSON
python3 -c "import json; json.load(open('/etc/docker/daemon.json'))"
sudo systemctl restart docker && sudo systemctl is-active docker
Keep every option in one place Pick either the systemd unit flags or daemon.json for each setting and remove it from the other. The daemon refuses to start when the same directive appears twice, so a duplicate is not a style problem that can wait; it is the whole failure. systemctl cat docker | grep -n ExecStart
sudo cat /etc/docker/daemon.json
Edit JSON with a JSON tool Use a parser to add or change keys, so the file is re-emitted as valid JSON every time instead of being patched as text. This removes the trailing comma class of failure permanently rather than fixing one instance of it. tmp=$(mktemp)
jq '."log-driver" = "json-file"' /etc/docker/daemon.json > "$tmp" \
&& sudo mv "$tmp" /etc/docker/daemon.json
Surface the daemon journal in the failing job Add a failure-only ste...

Powered by Readybot.io