Docker Error Guide: 'daemon.json: invalid character looking for beginning of object key string' — Fix the JSON
Fix Docker's daemon.json 'invalid character' startup error: locate the trailing comma or stray brace, validate with jq or python, read journalctl, and restart the daemon cleanly.
- #docker
- #troubleshooting
- #errors
- #configuration
Stuck on this Docker with AI error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
This error appears when the Docker daemon reads its configuration file and cannot parse it as valid JSON. The daemon refuses to start:
unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character '}' looking for beginning of object key string
The message comes straight from Go’s JSON parser. invalid character '}' looking for beginning of object key string almost always means a trailing comma — the parser saw a comma promising another "key": value pair, then hit the closing } instead of a new key. Because daemon.json is read at startup, a single stray comma or brace takes the whole Docker daemon down until the syntax is fixed.
Symptoms
sudo systemctl start dockerfails andsystemctl status dockershows the daemon in a failed/restart-loop state.dockercommands all fail withCannot connect to the Docker daemon at unix:///var/run/docker.sock.journalctl -u dockershows theinvalid character ... looking for beginning of object key stringline at each start attempt.- The failure started immediately after someone edited
/etc/docker/daemon.json(added a registry mirror, log opts, DNS, a runtime, etc.). - The exact character in the message varies —
'}',']', or','— but always points at a JSON syntax slip.
Common Root Causes
- A trailing comma after the last key/value pair in an object or array — the single most common cause of this exact message.
- A missing comma between two pairs, or a stray/duplicate closing
}or]. - Comments in the file — JSON has no comments; a
//or#line makes the parser fail. - Unquoted keys or values, or single quotes instead of double quotes.
- Two config sources fighting — options set both in
daemon.jsonand on thedockerdcommand line, or a merge that produced malformed JSON.
Diagnostic Workflow
First read the exact parser error and the file it names from the daemon log:
journalctl -u docker --no-pager --since '10 min ago' | grep -i 'daemon.json\|invalid character'
systemctl status docker --no-pager
Validate the file with a real JSON parser — this points at the offending line far more precisely than the daemon does:
jq . /etc/docker/daemon.json
python3 -m json.tool /etc/docker/daemon.json
jq will print something like parse error: ... at line 6, column 1, taking you straight to the trailing comma. A malformed file typically looks like this, with the comma after the last pair being the culprit:
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m" },
}
The corrected version simply drops the trailing comma:
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m" }
}
Docker can also validate its own configuration without fully starting, which confirms the fix before you restart the service:
sudo dockerd --validate --config-file /etc/docker/daemon.json
Once the file parses cleanly, start the daemon and confirm it is healthy:
sudo systemctl restart docker
docker info | head
Example Root Cause Analysis
An operator added a registry mirror to /etc/docker/daemon.json, restarted Docker, and the daemon would not come back — every docker command reported it could not reach the socket.
journalctl -u docker showed invalid character '}' looking for beginning of object key string. Running jq . /etc/docker/daemon.json reported parse error at line 5, column 1. Line 4 was the new "registry-mirrors": [...] entry — and the operator had appended it with a comma while it was the last key in the object:
{
"log-driver": "json-file",
"registry-mirrors": ["https://mirror.corp.internal"],
}
The trailing comma after the array told the parser to expect another key, but line 5 was the closing }. Removing the comma made jq pass, dockerd --validate succeeded, and sudo systemctl restart docker brought the daemon up. The root cause was purely syntactic — a leftover comma from editing — which jq’s line-and-column output identified in seconds.
Prevention Best Practices
- Always run
jq . /etc/docker/daemon.json(orpython3 -m json.tool) before restarting Docker after any edit — never restart on faith. - Use
dockerd --validate --config-file ...as a pre-flight check in provisioning and change scripts. - Keep
daemon.jsonunder configuration management (Ansible/Chef/Terraform) that renders valid JSON from templates, eliminating hand-edited commas. - Remember JSON has no comments and requires double quotes — do not paste in
//notes or single-quoted values. - Back up the working file before editing so you can restore instantly if a change breaks daemon startup.
Quick Command Reference
# Read the exact parser error
journalctl -u docker --no-pager --since '10 min ago' | grep 'invalid character'
systemctl status docker --no-pager
# Validate the JSON (pinpoints the bad line/column)
jq . /etc/docker/daemon.json
python3 -m json.tool /etc/docker/daemon.json
# Let Docker validate its own config without starting
sudo dockerd --validate --config-file /etc/docker/daemon.json
# Fix, then restart and confirm
sudo systemctl restart docker
docker info | head
Conclusion
daemon.json: invalid character ... looking for beginning of object key string is a JSON syntax error — nearly always a trailing comma — that stops the Docker daemon from starting at all. The path out is quick and deterministic: read the parser message in journalctl, run jq to get the exact line and column, remove the stray comma or brace, confirm with dockerd --validate, then restart. To keep it from recurring, validate every daemon.json edit before restarting and render the file from configuration management rather than editing it by hand.
Fixed it? Get 500 Docker with AI & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Stuck on this? Start guided troubleshooting
Open an interactive diagnostic session with this error already loaded. Work a step-by-step plan, record what each check returns, land on a root cause, and export a clean incident summary — no account needed to start.
Did this fix your issue?
Solved it a different way?
Share the fix that worked for you — reviewed, then published to help the next engineer.
That looks like it may contain a secret (key, token, password, or connection string). Please remove it — a note with a detected secret can’t be published.
Thanks — that helps. Published notes appear after a quick review.
Trending errors this week
The error guides other engineers are actually reading right now.
- 1mount: wrong fs type, bad option, bad superblock
- 2Docker 'failed to set up container networking': Fix the Bridge and IP Pool
- 3Docker 'failed to create shim task': How to Fix the containerd Runtime Error
- 4Transport endpoint is not connected
- 5modprobe: FATAL: Module not found
- 6mount: wrong fs type, bad option, bad superblock
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.