{"record":{"id":"9dd01caa0080d2ed","repo":"caddyserver/caddy","slug":"unknown-object-id-s","errorCode":null,"errorMessage":"unknown object ID '%s'","messagePattern":"unknown object ID '(.+?)'","errorType":"http","errorClass":"APIError","httpStatus":404,"severity":"error","filePath":"admin.go","lineNumber":1116,"sourceCode":"\t\t\tErr:        fmt.Errorf(\"request path is missing object ID\"),\n\t\t}\n\t}\n\tif parts[0] != \"\" || parts[1] != \"id\" {\n\t\treturn APIError{\n\t\t\tHTTPStatus: http.StatusBadRequest,\n\t\t\tErr:        fmt.Errorf(\"malformed object path\"),\n\t\t}\n\t}\n\tid := parts[2]\n\n\t// map the ID to the expanded path\n\trawCfgMu.RLock()\n\texpanded, ok := rawCfgIndex[id]\n\trawCfgMu.RUnlock()\n\tif !ok {\n\t\treturn APIError{\n\t\t\tHTTPStatus: http.StatusNotFound,\n\t\t\tErr:        fmt.Errorf(\"unknown object ID '%s'\", id),\n\t\t}\n\t}\n\n\t// piece the full URL path back together\n\tparts = append([]string{expanded}, parts[3:]...)\n\tr.URL.Path = path.Join(parts...)\n\n\treturn errInternalRedir\n}\n\nfunc handleStop(w http.ResponseWriter, r *http.Request) error {\n\tif r.Method != http.MethodPost {\n\t\treturn APIError{\n\t\t\tHTTPStatus: http.StatusMethodNotAllowed,\n\t\t\tErr:        fmt.Errorf(\"method not allowed\"),\n\t\t}\n\t}\n","sourceCodeStart":1098,"sourceCodeEnd":1134,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/admin.go#L1098-L1134","documentation":"Thrown by handleConfigID when the object ID extracted from the path is not present in Caddy's rawCfgIndex, the map of @id values to expanded config paths. It returns HTTP 404 'unknown object ID <id>'. The index is built from the current raw config, so the ID must exist in the loaded config right now.","triggerScenarios":"GET/POST/PUT/PATCH/DELETE to /id/<ID> where <ID> matches no @id field in the currently loaded config, e.g. after the object was deleted, the config was replaced, or Caddy restarted with a different Caddyfile.","commonSituations":"Referencing an @id that was removed or renamed in the Caddyfile; config swapped via a full PUT /config/ which drops old @id entries; Caddy reloaded with a different config file so prior IDs no longer resolve.","solutions":["GET the current config (curl http://localhost:2019/config/) and verify the @id value still exists","Re-add the @id annotation to the object in your Caddyfile/JSON and reload","If the ID legitimately changed, update your client to use the new @id or fall back to the canonical /config/ path"],"exampleFix":"# Caddyfile: give the object a stable @id\n# before\nroute /api/* {\n    respond \"ok\"\n}\n# after\n@api_route route /api/* {\n    respond \"ok\"\n}\n# then: curl http://localhost:2019/id/api_route","handlingStrategy":"validation","validationCode":"id=\"my-route\"\nexists=$(curl -s http://localhost:2019/config/ | jq --arg i \"$id\" 'tostring | contains(\"\\\"@id\\\": \\\"'\"$id\"'\\\"\")')\n[ \"$exists\" = \"true\" ] && curl http://localhost:2019/id/$id || echo \"ID not in config\"","typeGuard":null,"tryCatchPattern":"Treat HTTP 404 from /id/<ID> as 'object gone': re-fetch config, locate the new @id or canonical path, and retry once with the corrected address.","preventionTips":["Give objects stable @id annotations in the Caddyfile so IDs survive reloads","Re-resolve IDs after any full-config PUT or Caddyfile reload"],"tags":["caddy","admin-api","http","not-found","config"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}