highIntermediateSymptom-first#grafana#datasource#migration#dashboard#uid

Grafana dashboard panel shows 'Datasource with UID ... not found' after migration

Dashboard panels display 'Datasource with UID <uid> not found'

Likely source:configurationdeployment

Focused incident mode — strips away everything but this runbook.

Symptoms

  • Dashboard panels display 'Datasource with UID <uid> not found'
  • Panels go blank or show an error banner after a Grafana upgrade
  • Datasource list in Grafana settings shows a different UID than the dashboard expects
  • Importing a dashboard from another Grafana instance breaks all panels

UIDs are stable identifiers that survive Grafana upgrades but not delete-and-recreate. When migrating dashboards between instances, always re-import with datasource variable references instead of hardcoded UIDs.

Evidence to grab

Collect these artifacts before you change anything — they prove (or rule out) each cause.

  • Datasource UID in the dashboard JSON

    curl -s -H 'Authorization: Bearer <TOKEN>' http://<GRAFANA>/api/dashboards/uid/<DASH-UID> | jq '.dashboard.panels[].datasource.uid'
  • Available datasources

    curl -s -H 'Authorization: Bearer <TOKEN>' http://<GRAFANA>/api/datasources | jq '.[] | {id, uid, name, type}'

Diagnostic flow

Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.

Guided decision tree is ready.

Steps with commands, expected output, and pass/fail branches.

Ranked root causes

Evidence checklist

  • The dashboard references a UID that does not exist in /api/datasources
  • Datasource was recently deleted and recreated, or imported from another instance
  • The old UID appears in the dashboard JSON but not in the live datasource list

Confirm before fixing

curl -s -H 'Authorization: Bearer <TOKEN>' http://<GRAFANA>/api/datasources | jq '.[].uid'
READ

List all live datasource UIDs

Fix

curl -s -X PUT -H 'Authorization: Bearer <TOKEN>' -H 'Content-Type: application/json' http://<GRAFANA>/api/datasources/<DS-ID> -d '{"uid":"<OLD-UID>"}'
CHANGE

Update the datasource UID to match what the dashboard expects

Resolution runbook

Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.

1
curl -s -H 'Authorization: Bearer <TOKEN>' http://<GRAFANA>/api/datasources | jq '.[] | {uid, name, type}'
READ

List all datasource UIDs

2
curl -s -H 'Authorization: Bearer <TOKEN>' http://<GRAFANA>/api/dashboards/uid/<DASH-UID> | jq '[.dashboard.panels[].datasource.uid] | unique'
READ

Find which UIDs the dashboard references

3
curl -s -X PUT -H 'Authorization: Bearer <TOKEN>' -H 'Content-Type: application/json' http://<GRAFANA>/api/datasources/<DS-ID> -d '{"uid":"<CORRECT-UID>"}'
CHANGE

Update the datasource UID to match the dashboard

Prevention

  • Export dashboards with 'Export for sharing externally' to use template variables instead of UIDs.
  • Use Grafana provisioning (YAML files) for datasources so UIDs are deterministic and version-controlled.
  • Add a datasource UID consistency check to the Grafana upgrade runbook.
  • Avoid manually editing datasource UIDs in the database — use the API.

Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.