{"record":{"id":"6cfda974ae5dc19e","repo":"wtfutil/wtf","slug":"please-specify-apiurl-in-pi-hole-settings-e-g","errorCode":null,"errorMessage":" please specify 'apiUrl' in Pi-hole settings, e.g.\n apiUrl: http://<server>:<port>/admin/api.php","messagePattern":" please specify 'apiUrl' in Pi-hole settings, e\\.g\\.\n apiUrl: http://<server>:<port>/admin/api\\.php","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/pihole/client.go","lineNumber":306,"sourceCode":"\t\treturn qt, fmt.Errorf(\" failed to parse query types response\\n %s\", parseError(err))\n\t}\n\n\treturn qt, err\n}\n\nfunc checkServer(c http.Client, apiURL string) error {\n\tvar err error\n\n\tvar req *http.Request\n\n\tvar url *url2.URL\n\n\tif url, err = url2.Parse(apiURL); err != nil {\n\t\treturn fmt.Errorf(\" failed to parse API URL\\n %s\", parseError(err))\n\t}\n\n\tif url.Host == \"\" {\n\t\treturn fmt.Errorf(\" please specify 'apiUrl' in Pi-hole settings, e.g.\\n apiUrl: http://<server>:<port>/admin/api.php\")\n\t}\n\n\tif req, err = http.NewRequest(\"GET\", fmt.Sprintf(\"%s?version\",\n\t\turl.String()), http.NoBody); err != nil {\n\t\treturn fmt.Errorf(\"invalid request: %s\", parseError(err))\n\t}\n\n\tvar resp *http.Response\n\n\tif resp, err = c.Do(req); err != nil {\n\t\treturn fmt.Errorf(\" failed to connect to Pi-hole server\\n %s\", parseError(err))\n\t}\n\n\tdefer func() {\n\t\t_ = resp.Body.Close()\n\t}()\n\n\tif resp.StatusCode >= http.StatusBadRequest {","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/pihole/client.go#L288-L324","documentation":"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.","triggerScenarios":"url.Host == \"\" after url2.Parse(apiURL) in checkServer — the apiUrl key is absent, empty, or scheme-less like 'localhost/admin/api.php'.","commonSituations":"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.","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"],"exampleFix":"// before: no scheme, Host is empty\napiUrl: pi.hole/admin/api.php\n// after\napiUrl: http://pi.hole/admin/api.php","handlingStrategy":"validation","validationCode":"u, err := url.Parse(cfg.APIUrl)\nif err != nil || u.Host == \"\" {\n    return fmt.Errorf(\"apiUrl must be a full URL with host, e.g. http://pi.hole/admin/api.php; got %q\", cfg.APIUrl)\n}","typeGuard":null,"tryCatchPattern":"if err := widget.checkServer(*client, apiUrl); err != nil {\n    if strings.Contains(err.Error(), \"apiUrl\") {\n        log.Printf(\"configuration fix needed: %v\", err)\n    }\n}","preventionTips":["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"],"tags":["configuration","pi-hole","url","missing-setting"],"backgroundTag":"missing-config-value","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}