louislam/uptime-kuma · warning · Error
Invalid Docker response, is it Docker really a daemon?
Error message
Invalid Docker response, is it Docker really a daemon?
What it means
In testDockerHost(), after a successful axios.request to the daemon, the response body must be an array. When the array has more than one element, the first element must contain an `ImageID` key — that is the field the real Docker /containers/json endpoint returns per container. If it is missing, the endpoint answered with something that is array-shaped but not the Docker containers API (a reverse proxy error page split into chunks, a JSON array from a different service, etc.).
Source
Thrown at server/docker.js:95
if (dockerHost.dockerType === "socket") {
options.socketPath = dockerHost.dockerDaemon;
} else if (dockerHost.dockerType === "tcp") {
options.baseURL = DockerHost.patchDockerURL(dockerHost.dockerDaemon);
options.httpsAgent = new https.Agent(
await DockerHost.getHttpsAgentOptions(dockerHost.dockerType, options.baseURL)
);
}
try {
let res = await axios.request(options);
if (Array.isArray(res.data)) {
if (res.data.length > 1) {
if ("ImageID" in res.data[0]) {
return res.data.length;
} else {
throw new Error("Invalid Docker response, is it Docker really a daemon?");
}
} else {
return res.data.length;
}
} else {
throw new Error("Invalid Docker response, is it Docker really a daemon?");
}
} catch (e) {
if (e.code === "ECONNABORTED" || e.name === "CanceledError") {
throw new Error("Connection to Docker daemon timed out.");
} else {
throw e;
}
}
}
/**
* Since axios 0.27.X, it does not accept `tcp://` protocol.View on GitHub (pinned to 6b5ea01557)
Solutions
- Verify the daemon URL with `curl --unix-socket /var/run/docker.sock http://localhost/containers/json?all=true` (socket) or `curl https://host:2376/containers/json?all=true` (TCP) — the first element must include ImageID.
- Confirm you are hitting the Docker Engine API and not a registry or a different JSON service on the same port.
- Remove any reverse-proxy rewrite that alters the /containers/json response body.
- If using TLS, check the certificate path (data/docker-tls/<host>/) so you actually reach the daemon rather than a TLS-terminating proxy serving other content.
Example fix
// before
if (res.data.length > 1) {
if ("ImageID" in res.data[0]) {
return res.data.length;
} else {
throw new Error("Invalid Docker response, is it Docker really a daemon?");
}
}
// after — include a sample of what came back to aid debugging
throw new Error(`Invalid Docker response (no ImageID on item[0]); first item keys: ${Object.keys(res.data[0]).join(",")}`); Defensive patterns
Strategy: validation
Validate before calling
// Probe the endpoint shape yourself before relying on testDockerHost()
async function looksLikeDockerApi(baseURL, socketPath) {
const axios = require("axios");
const res = await axios.request({ url: "/containers/json?all=true", ...(socketPath ? { socketPath } : { baseURL }), timeout: 5000 });
return Array.isArray(res.data) && (res.data.length === 0 || "ImageID" in res.data[0]);
} Type guard
function isDockerContainerArray(data) {
return Array.isArray(data) && (data.length === 0 || data.every((c) => typeof c === "object" && c !== null && "ImageID" in c));
} Try / catch
try {
const count = await DockerHost.testDockerHost(dockerHost);
} catch (e) {
if (/Invalid Docker response/.test(e.message)) {
// the URL is reachable but is NOT the Docker API; reconfigure the daemon path
}
throw e;
} Prevention
- Smoke-test the daemon with curl before configuring it in the UI.
- Always hit /containers/json on the Docker Engine API, not the registry or a proxy root.
- Document the expected curl response so operators can self-verify.
When it happens
Trigger: Pointing a docker host at a URL/path that returns an array without ImageID: a registry API, a load balancer returning an array of backend info, a TCP host that is actually a different JSON service, or a proxy in front of the daemon rewriting responses.
Common situations: Misconfigured socketPath/baseURL (e.g. pointed at /v1.40/info by mistake); a TCP load balancer that round-robins to a non-docker service; an authenticated proxy returning a JSON error array.
Related errors
- Connection to Docker daemon timed out.
- Packet size must be between ${PING_PACKET_SIZE_MIN} and ${PI
- No Resolver Servers specified. Please specify at least one r
- docker host not found
- Embedded Mariadb supports only 'node' or 'root' user, but th
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/b27c683690e77e15.
Report an issue: GitHub.