caddyserver/caddy · error · APIError
malformed object path
Error message
malformed object path
What it means
Thrown by handleConfigID in Caddy's admin API when the request path's second segment is not the literal 'id'. After splitting on '/', the code requires parts[0]=="" and parts[1]=="id"; anything else (e.g. '/ids/foo' or '/ID/foo') yields HTTP 400 'malformed object path'.
Source
Thrown at admin.go:1104
}
return nil
}
func handleConfigID(w http.ResponseWriter, r *http.Request) error {
idPath := r.URL.Path
parts := strings.Split(idPath, "/")
if len(parts) < 3 || parts[2] == "" {
return APIError{
HTTPStatus: http.StatusBadRequest,
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...)View on GitHub (pinned to 50e54ee279)
Solutions
- Use the exact prefix /id/ directly after the admin address, e.g. http://localhost:2019/id/<ID>
- Check for a doubled path segment or base-URL joining bug in your HTTP client that shifts the path parts
- Remember the prefix is case-sensitive lowercase 'id'
Example fix
# before curl http://localhost:2019/ids/my-route # after curl http://localhost:2019/id/my-route
Defensive patterns
Strategy: validation
Validate before calling
import re
def valid_id_url(url: str) -> bool:
return re.fullmatch(r"https?://[^/]+/id/[^/]+", url) is not None Prevention
- Centralize admin URL construction in one helper that always emits /id/<ID>
- The prefix is lowercase 'id' and case-sensitive
When it happens
Trigger: Requests like GET /ids/my-route (typo in the 'id' prefix), /ID/foo (wrong case), or a path where the first segment is not empty. Any /id-style URL that does not start exactly with /id/.
Common situations: Typos in the endpoint prefix; clients that prepend an extra path component or base path so the split alignment shifts; assuming case-insensitive endpoints.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- request path is missing object ID
- unknown object ID '%s'
- method not allowed
- decoding request body: %w, at offset %d
- decoding request body: %w
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/8e314523ef868900.
Report an issue: GitHub.