SonarSource/sonarqube · error · org.sonar.db.RowNotFoundException

Metric key ' ' not found

Error message

Metric key '%s' not found

What it means

MetricDao.selectOrFailByKey throws RowNotFoundException when no metric matches the given key, for callers that require the metric row to exist. selectByKey returns null when absent; this method converts absence into an exception.

Solutions

  1. Verify the metric key exists (e.g. via api/metrics/search) and fix typos
  2. Install/reinstall the plugin that defines the custom metric
  3. Use selectByKey and handle null when the metric may legitimately be absent
  4. Handle RowNotFoundException with a clear message naming the missing metric key

Example fix

// before
MetricDto metric = metricDao.selectOrFailByKey(dbSession, "my_custom_metric");
// after
MetricDto metric = metricDao.selectByKey(dbSession, "my_custom_metric");
if (metric == null) {
  // metric not defined; skip or register it
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (key == null || key.isBlank()) {
  throw new IllegalArgumentException("Metric key is required");
}
if (metricDao.selectByKey(dbSession, key) == null) {
  throw new IllegalArgumentException("Metric " + key + " is not defined");
}

Try / catch

try {
  MetricDto metric = metricDao.selectOrFailByKey(dbSession, key);
} catch (RowNotFoundException e) {
  // return 404 / skip measure handling
}

Prevention

When it happens

Trigger: Calling selectOrFailByKey with a metric key that is not registered in the METRICS table (custom metric removed, typo, plugin providing the metric not installed, core metric renamed).

Common situations: Custom measures referencing a metric whose plugin was uninstalled; typos in metric keys in quality gate/measure code; metrics removed between SonarQube versions; case mismatches.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/4db493e725cb8ed4. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-db-dao/src/main/java/org/sonar/db/metric/MetricDao.java:49

import org.sonar.db.RowNotFoundException;

import static org.sonar.db.DatabaseUtils.executeLargeInputs;

public class MetricDao implements Dao {

  @CheckForNull
  public MetricDto selectByKey(DbSession session, String key) {
    return mapper(session).selectByKey(key);
  }

  public List<MetricDto> selectByKeys(final DbSession session, Collection<String> keys) {
    return executeLargeInputs(keys, mapper(session)::selectByKeys);
  }

  public MetricDto selectOrFailByKey(DbSession session, String key) {
    MetricDto metric = selectByKey(session, key);
    if (metric == null) {
      throw new RowNotFoundException(String.format("Metric key '%s' not found", key));
    }
    return metric;
  }

  public List<MetricDto> selectAll(DbSession session) {
    return mapper(session).selectAll();
  }

  public List<MetricDto> selectEnabled(DbSession session) {
    return mapper(session).selectAllEnabled(Pagination.all());
  }

  public List<MetricDto> selectEnabled(DbSession session, int page, int limit) {
    return mapper(session).selectAllEnabled(Pagination.forPage(page).andSize(limit));
  }

  public int countEnabled(DbSession session) {
    return mapper(session).countEnabled();

View on GitHub (pinned to 184c821202)