apache/druid · error · IllegalStateException

Failed to parse metric configuration

Error message

Failed to parse metric configuration

What it means

Prometheus emitter's Metrics.readConfig deserializes the metric definitions file into Map<String, Metric>. If the file is not parseable into that shape (invalid YAML/JSON or wrong structure), it throws ISE with 'Failed to parse metric configuration' during emitter setup.

Source

Thrown at extensions-contrib/prometheus-emitter/src/main/java/org/apache/druid/emitter/prometheus/Metrics.java:149

  }

  private Map<String, Metric> readConfig(String path)
  {
    try {
      InputStream is;
      if (Strings.isNullOrEmpty(path)) {
        log.info("Using default metric configuration");
        is = this.getClass().getClassLoader().getResourceAsStream("defaultMetrics.json");
      } else {
        log.info("Using metric configuration at [%s]", path);
        is = new FileInputStream(new File(path));
      }
      return mapper.readerFor(new TypeReference<Map<String, Metric>>()
      {
      }).readValue(is);
    }
    catch (IOException e) {
      throw new ISE(e, "Failed to parse metric configuration");
    }
  }

  public Map<String, DimensionsAndCollector> getRegisteredMetrics()
  {
    return registeredMetrics;
  }

  public static class Metric
  {
    public final SortedSet<String> dimensions;
    public final Type type;
    public final String help;
    public final double conversionFactor;
    public final double[] histogramBuckets;

    @JsonCreator
    public Metric(

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Validate the metrics YAML/JSON parses and maps metric names to Metric objects with the expected fields (type, help, dimensions, etc.)
  2. Fix YAML indentation/typos and ensure each entry includes required Metric properties
  3. Compare against the bundled default metrics definition file for the correct schema

Example fix

// before (bad YAML)
druid/request/converted/time:
  type: TIMER
  help: missing colon here
// after
druid/request/converted/time:
  type: TIMER
  help: Request conversion time
Defensive patterns

Strategy: validation

Validate before calling

Object cfg = new Yaml().load(metricsFile);
if (!(cfg instanceof Map)) throw new IllegalArgumentException("prometheus metrics config must be a map of metric name -> Metric");
((Map<?, ?>) cfg).forEach((k, v) -> { if (!(v instanceof Map)) throw new IllegalArgumentException("bad entry: " + k); });

Try / catch

try { Metrics.fromConfig(mapper, is); } catch (IllegalStateException e) { if (e.getMessage().contains("parse metric configuration")) { log.error("Check metricDefinitionsPath file: {}", e.getCause()); } }

Prevention

When it happens

Trigger: The prometheus emitter's metrics config file (druid.emitter.prometheus.metricDefinitionsPath or bundled default) contains malformed YAML/JSON or entries that don't match the expected Metric schema; read when the emitter is created.

Common situations: Custom metric definition files with YAML syntax errors, wrong field names in Metric entries, top-level list instead of map, or an empty/corrupt file.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/aeba4fc98c7b52ba. Report an issue: GitHub.