wtfutil/wtf · error
please specify 'apiUrl' in Pi-hole settings, e.g. apiUrl:
Error message
please specify 'apiUrl' in Pi-hole settings, e.g. apiUrl: http://<server>:<port>/admin/api.php
What it means
After parsing succeeds, checkServer requires the URL to have a host component. If url.Host is empty, the apiUrl setting is missing or incomplete (e.g. just a path or empty string), so the library tells the user to specify apiUrl in Pi-hole settings with an example value.
Source
Thrown at modules/pihole/client.go:306
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")
}
if req, err = http.NewRequest("GET", fmt.Sprintf("%s?version",
url.String()), http.NoBody); err != nil {
return fmt.Errorf("invalid request: %s", parseError(err))
}
var resp *http.Response
if resp, err = c.Do(req); err != nil {
return fmt.Errorf(" failed to connect to Pi-hole server\n %s", parseError(err))
}
defer func() {
_ = resp.Body.Close()
}()
if resp.StatusCode >= http.StatusBadRequest {View on GitHub (pinned to bb838c1ccb)
Solutions
- Add the apiUrl key under the Pi-hole module settings with a full URL including scheme and host
- Include the scheme (http:// or https://) — a bare hostname yields an empty Host
- Check YAML indentation so apiUrl is nested in the correct widget config block
Example fix
// before: no scheme, Host is empty apiUrl: pi.hole/admin/api.php // after apiUrl: http://pi.hole/admin/api.php
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(cfg.APIUrl)
if err != nil || u.Host == "" {
return fmt.Errorf("apiUrl must be a full URL with host, e.g. http://pi.hole/admin/api.php; got %q", cfg.APIUrl)
} Try / catch
if err := widget.checkServer(*client, apiUrl); err != nil {
if strings.Contains(err.Error(), "apiUrl") {
log.Printf("configuration fix needed: %v", err)
}
} Prevention
- Always specify scheme://host/path in apiUrl
- Check YAML nesting/indentation so apiUrl lands under the Pi-hole widget
- Test the exact apiUrl value in a browser before adding it to config
When it happens
Trigger: url.Host == "" after url2.Parse(apiURL) in checkServer — the apiUrl key is absent, empty, or scheme-less like 'localhost/admin/api.php'.
Common situations: Fresh install where apiUrl was never configured, YAML indentation mistake putting apiUrl under the wrong key, or writing 'pi.hole/admin/api.php' without the http:// scheme so Parse yields no Host.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- invalid request: %s
- invalid base URL: %w
- command shell not defined in $SHELL environment variable
- client was not initialized
- github client v3 failed to load
AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03).
Data as JSON: /api/errors/6cfda974ae5dc19e.
Report an issue: GitHub.