grafana/grafana · error · Error

Datasource ${describeRef(ref)} was not found

Error message

Datasource ${describeRef(ref)} was not found

What it means

getDataSourceInstance(ref) resolves a data source by uid/name/DataSourceRef with optional template scopedVars. It first calls getDataSourceInstanceSettings(ref, scopedVars); if that returns null/undefined (no matching datasource in the registry/config), it throws 'Datasource <ref> was not found'. describeRef renders the ref (uid or name) into the message.

Source

Thrown at packages/grafana-runtime/src/services/dataSource/dataSource.ts:53

 */
export async function getDataSourceInstance(
  ref?: DataSourceRef | string | null,
  scopedVars?: ScopedVars
): Promise<DataSourceApi> {
  if (isExpressionReference(ref)) {
    const expressionDs = getExpressionDataSourceInstance();
    if (!expressionDs) {
      throw new Error(
        'Expression datasource has not been initialised. Call setExpressionDataSourceInstance during application boot.'
      );
    }
    return expressionDs;
  }

  try {
    let settings = await getDataSourceInstanceSettings(ref, scopedVars);
    if (!settings) {
      throw new Error(`Datasource ${describeRef(ref)} was not found`);
    }

    // When ref is a template variable, the settings keep the variable string in uid/name
    // (e.g. "${datasource}") with the resolved uid in rawRef — correct for the settings API,
    // but a plugin instance built from them would carry the variable as its identity. Legacy
    // DatasourceSrv.get() interpolates and returns the concrete instance, so re-resolve
    // through rawRef and construct/cache from the concrete settings.
    if (settings.rawRef && settings.rawRef.uid !== settings.uid) {
      settings = await getDataSourceInstanceSettings(settings.rawRef);
      if (!settings) {
        throw new Error(`Datasource ${describeRef(ref)} was not found`);
      }
    }

    const cacheUid = settings.uid;

    const cached = getCachedPlugin(cacheUid);
    if (cached) {

View on GitHub (pinned to ae3104e369)

Solutions

  1. Verify the uid/name exists via getDataSourceInstanceSettings(ref) or the Data Sources UI.
  2. When importing dashboards, remap datasource refs through the import dialog or update the JSON.
  3. Ensure template variables resolve to a real datasource the user can access.
  4. Re-provision or recreate the deleted datasource with the same uid.

Example fix

// before
const ds = await getDataSourceInstance({ uid: savedPanel.datasourceUid });

// after: guard before use
const settings = await getDataSourceInstanceSettings({ uid: savedPanel.datasourceUid });
if (!settings) { handleMissingDatasource(savedPanel.datasourceUid); return; }
const ds = await getDataSourceInstance({ uid: settings.uid });
Defensive patterns

Strategy: validation

Validate before calling

import { getDataSourceInstanceSettings, type DataSourceRef } from '@grafana/runtime';

async function datasourceExists(ref: DataSourceRef | string): Promise<boolean> {
  return Boolean(await getDataSourceInstanceSettings(ref));
}

Try / catch

try {
  const ds = await getDataSourceInstance(ref);
} catch (e) {
  if (/Datasource .* was not found/.test((e as Error).message)) {
    showDatasourcePicker(ref);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling getDataSourceInstance({ uid: 'nonexistent-uid' }); a dashboard JSON referencing a datasource uid that does not exist in this Grafana instance; a template variable resolving to an empty or missing datasource.

Common situations: Importing a dashboard from another Grafana whose datasource uids do not exist locally; deleting a datasource still referenced by panels/alerts; stale or typo'd uid in provisioning; permission/RBAC changes hiding the datasource from the current user.

Related errors


AI-assisted analysis of grafana/grafana@ae3104e369 (2026-08-12). Data as JSON: /api/errors/b9472e93586ca0a5. Report an issue: GitHub.