caddyserver/caddy · error · APIError

unknown object ID '%s'

Error message

unknown object ID '%s'

What it means

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.

Source

Thrown at admin.go:1116

			Err:        fmt.Errorf("request path is missing object ID"),
		}
	}
	if parts[0] != "" || parts[1] != "id" {
		return APIError{
			HTTPStatus: http.StatusBadRequest,
			Err:        fmt.Errorf("malformed object path"),
		}
	}
	id := parts[2]

	// map the ID to the expanded path
	rawCfgMu.RLock()
	expanded, ok := rawCfgIndex[id]
	rawCfgMu.RUnlock()
	if !ok {
		return APIError{
			HTTPStatus: http.StatusNotFound,
			Err:        fmt.Errorf("unknown object ID '%s'", id),
		}
	}

	// piece the full URL path back together
	parts = append([]string{expanded}, parts[3:]...)
	r.URL.Path = path.Join(parts...)

	return errInternalRedir
}

func handleStop(w http.ResponseWriter, r *http.Request) error {
	if r.Method != http.MethodPost {
		return APIError{
			HTTPStatus: http.StatusMethodNotAllowed,
			Err:        fmt.Errorf("method not allowed"),
		}
	}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. GET the current config (curl http://localhost:2019/config/) and verify the @id value still exists
  2. Re-add the @id annotation to the object in your Caddyfile/JSON and reload
  3. If the ID legitimately changed, update your client to use the new @id or fall back to the canonical /config/ path

Example fix

# Caddyfile: give the object a stable @id
# before
route /api/* {
    respond "ok"
}
# after
@api_route route /api/* {
    respond "ok"
}
# then: curl http://localhost:2019/id/api_route
Defensive patterns

Strategy: validation

Validate before calling

id="my-route"
exists=$(curl -s http://localhost:2019/config/ | jq --arg i "$id" 'tostring | contains("\"@id\": \"'"$id"'\"")')
[ "$exists" = "true" ] && curl http://localhost:2019/id/$id || echo "ID not in config"

Try / catch

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.

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/9dd01caa0080d2ed. Report an issue: GitHub.