Broken panel¶
A Grafana dashboard panel queries a Prometheus metric that does not exist.
Class: broken-panel
Severity: Medium
Category: dashboard_hygiene
Detected by: remetric dashboards broken, remetric scan
What it means¶
The panel's PromQL target references a metric name that is not in Prometheus head series and is not declared as the output of any recording rule. The panel will render as empty (no data) or as a flat line, and the user will see a silent gap rather than the expected signal.
Why it matters¶
Empty dashboard tiles are dangerous because they look the same as a system that is fine. An on-call engineer scanning a dashboard for problems can miss a real issue because the relevant tile shows "no data" instead of the metric they expect. A scan that surfaces every (dashboard, missing-metric) pair lets you either restore the metric or remove the dead query.
How remetric detects it¶
- Build the set of "known metrics":
- Every metric name returned by
/api/v1/label/__name__/values. - Every recording-rule output name returned by
/api/v1/rules(a freshly-added recording rule counts as known even before it emits its first sample).
- Every metric name returned by
- For each Grafana dashboard, parse every panel's Prometheus target with the PromQL parser and extract referenced metric names.
- Any extracted name not in the known set is "missing". Findings
are grouped by
(dashboard, missing-metric)so 50 panels in one dashboard referencing the same removed metric collapse into a single finding listing the affected panels.
Known false positives¶
- Intermittent metrics. A metric that is only present during
scheduled cron-job runs may appear missing during a scan that
runs between executions. Suppress with
--ignore-metric <regex>. - Freshly-rotated retention. If a metric is in long-term storage but no longer in head series, it counts as missing. Most users do not hit this because head-series retention is usually 15 days or more.
- VictoriaMetrics without
--vmalert. Recording rules live in thevmalertprocess, not invmselect. When--vmalertis not provided, recording outputs are not visible to remetric and any panel querying a recording-rule output is reported as broken. The analyzer surfaces this case as a warning rather than failing.
How to fix¶
Pick one of:
- Restore the metric. Re-enable the scrape job, fix the exporter, or add back the recording rule that emits the metric.
- Remove the dead query. Edit the dashboard in Grafana, delete the panel or rewrite its query to use a metric that still exists.
- Suppress. If the dashboard is known-stale and you cannot
delete it yet, use
--ignore-dashboard "Legacy.*"(anchored regex against the dashboard title).
Sample JSON¶
{
"id": "broken-panel:abc123:node_disk_io_now",
"severity": "medium",
"category": "dashboard_hygiene",
"class": "broken-panel",
"title": "dashboard \"Frontend SLOs\" references missing metric \"node_disk_io_now\"",
"metric": "node_disk_io_now",
"dashboard": "Frontend SLOs",
"evidence": {
"description": "2 panel(s) in dashboard \"Frontend SLOs\" query \"node_disk_io_now\" which is not present in head series or recording-rule outputs",
"sample_values": ["Disk I/O - last 5m", "Disk I/O - last 1h"]
},
"fix": {
"type": "edit_dashboard",
"config": "Edit dashboard \"Frontend SLOs\" (https://grafana.example.com/d/abc123/frontend-slos)\nand either:\n 1. Restore metric \"node_disk_io_now\" (...)\n 2. Remove/replace the broken queries in panel(s):\n - Disk I/O - last 5m\n - Disk I/O - last 1h\nReference: https://remetric.dev/findings/broken-panel"
},
"impact": {
"series_reduction": 0,
"percentage": 0,
"estimation_method": "broken_panel"
},
"documentation_url": "https://remetric.dev/findings/broken-panel"
}