{"record":{"id":"60223d26ef52704d","repo":"glanceapp/glance","slug":"session-id-check-request-returned-status-s","errorCode":null,"errorMessage":"session ID check request returned status %s","messagePattern":"session ID check request returned status (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/widget-dns-stats.go","lineNumber":680,"sourceCode":"\n\treturn jsonResponse.Session.SID, nil\n}\n\nfunc checkPiholeSessionIDIsValid(instanceURL string, client *http.Client, sessionID string) (bool, error) {\n\trequest, err := http.NewRequest(\"GET\", instanceURL+\"/api/auth\", nil)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"creating session ID check request: %v\", err)\n\t}\n\trequest.Header.Set(\"x-ftl-sid\", sessionID)\n\n\tresponse, err := client.Do(request)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdefer response.Body.Close()\n\n\tif response.StatusCode != http.StatusOK && response.StatusCode != http.StatusUnauthorized {\n\t\treturn false, fmt.Errorf(\"session ID check request returned status %s\", response.Status)\n\t}\n\n\treturn response.StatusCode == http.StatusOK, nil\n}\n\ntype technitiumStatsResponse struct {\n\tResponse struct {\n\t\tStats struct {\n\t\t\tTotalQueries   int `json:\"totalQueries\"`\n\t\t\tBlockedQueries int `json:\"totalBlocked\"`\n\t\t\tBlockedZones   int `json:\"blockedZones\"`\n\t\t\tBlockListZones int `json:\"blockListZones\"`\n\t\t} `json:\"stats\"`\n\t\tMainChartData struct {\n\t\t\tDatasets []struct {\n\t\t\t\tLabel string `json:\"label\"`\n\t\t\t\tData  []int  `json:\"data\"`\n\t\t\t} `json:\"datasets\"`","sourceCodeStart":662,"sourceCodeEnd":698,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-dns-stats.go#L662-L698","documentation":"After calling GET <instanceURL>/api/auth with the x-ftl-sid header, Pi-hole returned an HTTP status other than 200 (valid session) or 401 (expired session). Any other status (e.g. 500, 502, 404) is treated as an unexpected condition and reported with the raw response status string.","triggerScenarios":"Pi-hole API returns 404 (wrong URL path / not a Pi-hole v6 API), 500 (Pi-hole FTL crash), 502/503 (reverse proxy in front of Pi-hole is down or misrouting), or a redirect target that answers with a non-200/401 code.","commonSituations":"Pointing the widget at a Pi-hole v5 instance (which lacks /api/auth); a reverse proxy (nginx/Traefik) returning 502 because the upstream is down; pointing at the admin UI base path instead of the API host; Pi-hole FTL service restarting.","solutions":["Verify Pi-hole is v6+ and reachable: curl -i <instanceURL>/api/auth should return 200 or 401","If a reverse proxy is configured, check its upstream routing and that the Pi-hole container/service is up","Ensure the url: field points at the Pi-hole base (e.g. http://pi.hole) without extra paths","Check Pi-hole FTL logs (pihole-FTL.log) for crashes if it returns 500"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"resp, err := http.Get(instanceURL + \"/api/auth\") // smoke test\nif err != nil || (resp.StatusCode != 200 && resp.StatusCode != 401) {\n    // endpoint not speaking the Pi-hole v6 API; fix URL/proxy before enabling the widget\n}","typeGuard":null,"tryCatchPattern":"ok, err := checkPiholeSessionIDIsValid(instanceURL, client, sid)\nif err != nil {\n    // treat as transient: skip authed queries this cycle, retry next update\n    slog.Warn(\"pi-hole session check error\", \"error\", err)\n    return\n}\nif !ok {\n    // session expired: re-authenticate\n}","preventionTips":["Health-check /api/auth in your deployment probe to catch proxy/upstream breakage early","Pin the Pi-hole version (v6+) in your compose file so the auth API cannot disappear in an upgrade surprise","Monitor reverse-proxy 5xx rates on the Pi-hole route"],"tags":["pi-hole","http-status","network","reverse-proxy"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}