Grafana Error Guide: 'Data source not found' — Fix Datasource UID Mismatch After Import
Fix 'Data source not found' in Grafana: diagnose datasource UID mismatch after dashboard import or provisioning, unresolved ${DS_*} inputs, and deleted datasources.
- #grafana
- #troubleshooting
- #errors
- #datasource
Overview
Grafana panels reference their datasource by an immutable uid, not by name. When a dashboard is imported, copied between Grafana instances, or provisioned from files, that uid frequently does not exist on the target instance — so every panel fails to load with “Data source not found.”
The literal errors you will see, either on a panel or in the log:
Data source not found
Datasource ${DS_PROMETHEUS} was not found
level=error msg="Data source not found" uid=abc123def logger=context
The tell is that panels render an inline error while the datasource itself is perfectly healthy on the Datasources page — the dashboard simply points at a UID that this Grafana does not have.
Symptoms
- Every panel shows “Data source not found” immediately, before any query runs.
- The datasource dropdown in panel edit shows an unresolved
${DS_PROMETHEUS}input. - A newly imported or provisioned dashboard is broken while hand-built ones work.
- After migrating Grafana or recreating a datasource, previously working dashboards break.
Common Root Causes
1. UID mismatch after import between instances
The exported JSON hard-codes the source instance’s datasource UID. The target instance generated a different UID for the same datasource, so the reference dangles.
2. Unresolved ${DS_*} import input
Dashboards exported with “Export for sharing externally” contain __inputs placeholders. If imported via API/provisioning without mapping the input, the literal ${DS_PROMETHEUS} string is stored as the datasource.
3. Datasource was deleted or recreated
Deleting and re-adding a datasource assigns a new UID. Old dashboards keep the stale UID.
4. Provisioned datasource has no fixed uid
A provisioning YAML without an explicit uid gets a random one on each provision, so file-provisioned dashboards that hard-code a UID drift out of sync.
Diagnostic Workflow
Step 1: Find the UID the panel is asking for
Open the panel JSON (panel → Inspect → Panel JSON) and note the datasource.uid, or grep the dashboard JSON on disk:
grep -oE '"uid": *"[^"]+"' /var/lib/grafana/dashboards/my-dashboard.json | sort -u
Step 2: List the UIDs that actually exist
curl -s -H "Authorization: Bearer $GRAFANA_TOKEN" \
http://localhost:3000/api/datasources | jq '.[] | {name, uid, type}'
If the panel’s UID does not appear here, that is the whole problem.
Step 3: Check the server log for the missing UID
sudo journalctl -u grafana-server --no-pager | grep -i "data source not found" | tail -20
kubectl logs deploy/grafana -n monitoring | grep -i "not found" | tail -20
grep -i "not found" /var/log/grafana/grafana.log | tail -20
Step 4: Pin a stable UID in provisioning
Give the datasource an explicit, stable uid so it survives re-provisioning and matches dashboards:
# /etc/grafana/provisioning/datasources/prometheus.yaml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
uid: prometheus-main # stable, referenced by dashboards
access: proxy
url: http://prometheus:9090
isDefault: true
Then reference that same uid (or ${DS_PROMETHEUS} mapped to it) in the dashboard JSON.
Example Root Cause Analysis
An engineer exports a dashboard from staging and imports the JSON into production via the provisioning folder. In production every panel shows:
Datasource ${DS_PROMETHEUS} was not found
Inspecting the panel JSON shows "datasource": {"type": "prometheus", "uid": "${DS_PROMETHEUS}"} and an __inputs block. Because the file was dropped into provisioning without resolving the input, the literal placeholder string was stored as the UID.
Fix: give the production Prometheus datasource a fixed uid: prometheus-main in provisioning, then edit the dashboard JSON to replace ${DS_PROMETHEUS} with prometheus-main (or import through the UI, which prompts you to map the input). Reload provisioning and the panels resolve. The root cause was importing a “share externally” export without mapping its datasource input.
Prevention Best Practices
- Assign every provisioned datasource an explicit, stable
uidin/etc/grafana/provisioning/datasources/so it never drifts. - Standardize datasource UIDs across environments (staging = prod) so exports import cleanly.
- Prefer UI import (which prompts for datasource mapping) or a script that rewrites
${DS_*}inputs to real UIDs before provisioning. - Never delete-and-recreate a datasource in place; edit it so the UID is preserved.
- Keep dashboards and datasources in the same code repo so they version together; see more Grafana guides.
Quick Command Reference
# UID(s) a dashboard is asking for
grep -oE '"uid": *"[^"]+"' /var/lib/grafana/dashboards/my-dashboard.json | sort -u
# UIDs that actually exist on this Grafana
curl -s -H "Authorization: Bearer $GRAFANA_TOKEN" \
http://localhost:3000/api/datasources | jq '.[] | {name, uid, type}'
# Server log for the missing-UID error
sudo journalctl -u grafana-server | grep -i "data source not found" | tail -20
kubectl logs deploy/grafana -n monitoring | grep -i "not found" | tail -20
# Pin a stable uid in provisioning, then reload
# /etc/grafana/provisioning/datasources/prometheus.yaml -> uid: prometheus-main
Conclusion
“Data source not found” is almost always a UID mismatch, not a broken datasource. The fix is to make UIDs match:
- Read the UID (or
${DS_*}placeholder) the panel is requesting from the panel JSON. - List the datasources that exist and confirm the UID is absent.
- Give provisioned datasources explicit, stable UIDs and reference those in dashboards.
- Import via a path that resolves
${DS_*}inputs to real UIDs.
Standardize UIDs across environments once and this class of error disappears from every future import.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.