louislam/uptime-kuma · error · Error

docker host not found

Error message

docker host not found

What it means

DockerHost.save() with a non-null dockerHostID performs an ownership-scoped lookup: `findOne("docker_host", " id = ? AND user_id = ? ", [dockerHostID, userID])`. A miss means either the docker host does not exist or it belongs to a different user. Both branches are reported the same way on purpose — leaking 'exists but not yours' would be an info disclosure.

Source

Thrown at server/docker.js:28

    static CertificateFileNameCA = "ca.pem";
    static CertificateFileNameCert = "cert.pem";
    static CertificateFileNameKey = "key.pem";

    /**
     * Save a docker host
     * @param {object} dockerHost Docker host to save
     * @param {?number} dockerHostID ID of the docker host to update
     * @param {number} userID ID of the user who adds the docker host
     * @returns {Promise<Bean>} Updated docker host
     */
    static async save(dockerHost, dockerHostID, userID) {
        let bean;

        if (dockerHostID) {
            bean = await R.findOne("docker_host", " id = ? AND user_id = ? ", [dockerHostID, userID]);

            if (!bean) {
                throw new Error("docker host not found");
            }
        } else {
            bean = R.dispense("docker_host");
        }

        bean.user_id = userID;
        bean.docker_daemon = dockerHost.dockerDaemon;
        bean.docker_type = dockerHost.dockerType;
        bean.name = dockerHost.name;

        await R.store(bean);

        return bean;
    }

    /**
     * Delete a Docker host
     * @param {number} dockerHostID ID of the Docker host to delete

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Refresh the docker-hosts list in the UI and retry against a current id.
  2. Confirm the authenticated user is the owner of that docker host; if not, have the owner perform the edit or re-create the host under your account.
  3. If the row was deleted, create a new docker host instead of updating the old id.
  4. Check the server logs for the preceding query — the id/userID pair will show exactly why no row matched.

Example fix

// before — update without existence check
const bean = await R.findOne("docker_host", " id = ? AND user_id = ? ", [dockerHostID, userID]);
if (!bean) {
    throw new Error("docker host not found");
}

// after — return a 404-shaped error so the API layer can map it
if (!bean) {
    const err = new Error("docker host not found");
    err.status = 404;
    throw err;
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify ownership before calling DockerHost.save(..., dockerHostID, userID)
const { R } = require("redbean-node");
async function userOwnsDockerHost(dockerHostID, userID) {
    const row = await R.findOne("docker_host", " id = ? AND user_id = ? ", [dockerHostID, userID]);
    return row !== null;
}

Type guard

function isOwnedByUser(row, userID) {
    return !!row && Number(row.user_id) === Number(userID);
}

Try / catch

try {
    await DockerHost.save(dockerHost, dockerHostID, userID);
} catch (e) {
    if (/docker host not found/.test(e.message)) {
        // return 404 to the client; refresh the list in the UI
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling the PUT /api/docker-hosts/{id} endpoint (which routes to save) with an id that was deleted, never existed, or was created by another user account. Also hit if the userID passed in does not match the session user due to a session/auth bug.

Common situations: Multi-user instances where one user tries to edit another's docker host; stale frontend state after another user deleted the host; a URL/ID typo in a direct API call.

Related errors


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/d7373d8750521aeb. Report an issue: GitHub.