wtfutil/wtf · error
failed to parse query types response %s
Error message
failed to parse query types response %s
What it means
This error comes from the Pi-hole widget's getQueryTypes function when the HTTP response body from the Pi-hole API cannot be unmarshaled into the query-types data structure. The library fetched the top/query-types endpoint successfully but the JSON payload did not match the expected shape. parseError wraps the underlying json.Unmarshal error with source context.
Source
Thrown at modules/pihole/client.go:288
defer func() {
if closeErr := resp.Body.Close(); closeErr != nil {
return
}
}()
if resp.StatusCode >= http.StatusBadRequest {
return qt, fmt.Errorf(" failed to retrieve version from Pi-hole server\n http status code: %d",
resp.StatusCode)
}
var rBody []byte
if rBody, err = io.ReadAll(resp.Body); err != nil {
return qt, fmt.Errorf(" failed to read top clients response\n %s", parseError(err))
}
if err = json.Unmarshal(rBody, &qt); err != nil {
return qt, fmt.Errorf(" failed to parse query types response\n %s", parseError(err))
}
return qt, err
}
func checkServer(c http.Client, apiURL string) error {
var err error
var req *http.Request
var url *url2.URL
if url, err = url2.Parse(apiURL); err != nil {
return fmt.Errorf(" failed to parse API URL\n %s", parseError(err))
}
if url.Host == "" {
return fmt.Errorf(" please specify 'apiUrl' in Pi-hole settings, e.g.\n apiUrl: http://<server>:<port>/admin/api.php")View on GitHub (pinned to bb838c1ccb)
Solutions
- Verify the Pi-hole API version is 3-compatible and the apiUrl points to the correct api.php endpoint
- Confirm auth settings (API token/webpassword) are correct so Pi-hole returns JSON, not an auth/HTML page
- Curl the query types endpoint manually (apiUrl?getQueryTypes) and inspect the raw response for HTML or schema drift
- Update the widget/library if your Pi-hole version changed its JSON schema
Example fix
// before: apiUrl pointing at a dashboard URL returning HTML apiUrl: http://pi.hole/admin/ // after: apiUrl pointing at the api.php endpoint apiUrl: http://pi.hole/admin/api.php
Defensive patterns
Strategy: validation
Validate before calling
resp, err := http.Get(apiURL + "?getQueryTypes")
if err == nil {
var probe struct{ QueryTypes map[string]int `json:"query_types"` }
if jsonErr := json.NewDecoder(resp.Body).Decode(&probe); jsonErr != nil {
// config/auth problem: response is not expected JSON
}
} Try / catch
qt, err := widget.getQueryTypes()
if err != nil {
log.Printf("query types unavailable, skipping panel: %v", err)
return
} Prevention
- Verify apiUrl returns JSON (not HTML) with curl before configuring
- Keep Pi-hole API version compatible with the widget
- Set a valid API token so auth pages are never returned
When it happens
Trigger: io.ReadAll succeeded but json.Unmarshal(rBody, &qt) failed while parsing the query types endpoint response in getQueryTypes (called from getTopClientsView).
Common situations: Pi-hole returns an HTML login page instead of JSON (missing/expired auth token), the apiUrl points at Pi-hole v5/v6 whose response schema differs, a proxy or captive portal returns an error page, or the response is empty/truncated.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- invalid response returned from Pi-hole Server %s
- failed to parse JQL search response: %v
- failed to parse issue %s: %v
- failed to retrieve status: check provided api URL and token
- failed to retrieve top items: check provided api URL and to
AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03).
Data as JSON: /api/errors/754dded0bf248bf7.
Report an issue: GitHub.