{"record":{"id":"0a5ff8a10dca39c5","repo":"gethomepage/homepage","slug":"http-status-getting-data-from-glances-api-data","errorCode":null,"errorMessage":"HTTP ${status} getting data from glances API. Data: ${data.toString()}","messagePattern":"HTTP (.+?) getting data from glances API\\. Data: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"src/pages/api/widgets/glances.js","lineNumber":39,"sourceCode":"  if (privateWidgetOptions.username && privateWidgetOptions.password) {\n    headers.Authorization = `Basic ${Buffer.from(\n      `${privateWidgetOptions.username}:${privateWidgetOptions.password}`,\n    ).toString(\"base64\")}`;\n  }\n  const params = { method: \"GET\", headers };\n\n  const [status, , data] = await httpProxy(apiUrl, params);\n\n  if (status === 401) {\n    errorMessage = `Authorization failure getting data from glances API. Data: ${data.toString()}`;\n    logger.error(errorMessage);\n    throw new Error(errorMessage);\n  }\n\n  if (status !== 200) {\n    errorMessage = `HTTP ${status} getting data from glances API. Data: ${data.toString()}`;\n    logger.error(errorMessage);\n    throw new Error(errorMessage);\n  }\n\n  return JSON.parse(Buffer.from(data).toString());\n}\n\nexport default async function handler(req, res) {\n  const { index, cputemp: includeCpuTemp, uptime: includeUptime, disk: includeDisks, version } = req.query;\n\n  const privateWidgetOptions = await getPrivateWidgetOptions(\"glances\", index);\n  privateWidgetOptions.version = parseVersionForUrl(version, 3);\n\n  try {\n    const cpuData = await retrieveFromGlancesAPI(privateWidgetOptions, \"cpu\");\n    const loadData = await retrieveFromGlancesAPI(privateWidgetOptions, \"load\");\n    const memoryData = await retrieveFromGlancesAPI(privateWidgetOptions, \"mem\");\n    const data = {\n      cpu: cpuData,\n      load: loadData,","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/gethomepage/homepage/blob/b6dca1ae033e613d8e692f9a161a3cc53a5a2857/src/pages/api/widgets/glances.js#L21-L57","documentation":"Catch-all thrown when the Glances API returns any non-200 status other than 401 (which is handled separately). Includes the status code and response body so the operator can see what the upstream actually said.","triggerScenarios":"retrieveFromGlancesAPI() calls httpProxy, status is not 401 and not 200. Typical causes: 404 (wrong version/endpoint), 503/502 (Glances down or behind a failing proxy), 500 (Glances error reading a sensor), connection-reset surfaced as a non-200 status.","commonSituations":"Version mismatch — widget requests /api/4/... but Glances is v3 (or vice-versa); Glances container restarting or crashed; reverse proxy misrouting; endpoint not supported by this Glances build.","solutions":["Read the status and `Data` body in the message — a 404 means wrong path/version, a 5xx means upstream fault.","Confirm the `version` field matches the running Glances major version (Homepage defaults to 3 via parseVersionForUrl).","Curl the exact apiUrl the widget builds: `${url}/api/${version}/${endpoint}`.","Restart/check the Glances service if 5xx persists."],"exampleFix":"// before (wrong version)\nwidget:\n  type: glances\n  url: http://glances:61108\n  version: 4   # but Glances is v3\n\n// after\nwidget:\n  type: glances\n  url: http://glances:61108\n  version: 3","handlingStrategy":"try-catch","validationCode":"async function probeGlances(url, version, endpoint) {\n  const res = await fetch(`${url}/api/${version}/${endpoint}`);\n  return { ok: res.ok, status: res.status };\n}\n// before rendering: if (!(await probeGlances(url, 3, 'cpu')).ok) show stale data","typeGuard":null,"tryCatchPattern":"try {\n  const data = await retrieveFromGlancesAPI(options, endpoint);\n  return data;\n} catch (err) {\n  if (/^HTTP \\d+ getting data from glances API/.test(err.message)) {\n    const status = Number(err.message.match(/HTTP (\\d+)/)?.[1]);\n    // degrade gracefully based on status\n  }\n  throw err;\n}","preventionTips":["Match the widget version to the running Glances major version.","Health-check Glances before relying on the widget.","Treat 5xx as transient; surface last-known-good values in the UI.","Curl the exact apiUrl the widget builds to reproduce the upstream response."],"tags":["widget","glances","network","http","upstream"],"backgroundTag":null,"analyzedSha":"b6dca1ae033e613d8e692f9a161a3cc53a5a2857","analyzedAt":"2026-08-13T04:48:44.121Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}