apache/druid · error · IllegalStateException

Failed to parse metrics and dimensions

Error message

Failed to parse metrics and dimensions

What it means

Opentsdb emitter's EventConverter.readMap deserializes the metrics/dimensions YAML/JSON config file into Map<String, Set<String>>. If the stream cannot be parsed as that structure (malformed YAML, wrong shape), it throws ISE with 'Failed to parse metrics and dimensions'.

Source

Thrown at extensions-contrib/opentsdb-emitter/src/main/java/org/apache/druid/emitter/opentsdb/EventConverter.java:123

  }

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

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Validate the metrics/dimensions file is well-formed YAML/JSON and a map of metric-name -> list of strings
  2. Fix indentation and ensure values are lists, e.g. `my.metric: [host, service]`
  3. Load the file through a YAML linter/parser locally before deploying

Example fix

// before (bad YAML)
metrics:
  requests: host, service
// after
metrics:
  requests:
    - host
    - service
Defensive patterns

Strategy: validation

Validate before calling

Map<String, Set<String>> parsed = new Yaml().load(configFile);
if (parsed == null || parsed.isEmpty()) throw new IllegalArgumentException("opentsdb metrics config must be a non-empty map");
parsed.values().forEach(v -> { if (!(v instanceof Set || v instanceof List)) throw new IllegalArgumentException("values must be lists of dimensions"); });

Try / catch

try { new OpentsdbEmitter(config, mapper); } catch (IllegalStateException e) { if (e.getMessage().contains("parse metrics")) { validateConfigFile(path); } }

Prevention

When it happens

Trigger: The opentsdb emitter's metric/dimension definition file contains invalid YAML/JSON, or its top-level structure is not an object mapping metric names to arrays/sets of strings; read during emitter construction.

Common situations: Hand-edited metrics config with indentation errors, using a list at top level instead of a map, or values written as comma-separated strings instead of lists.

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/16f0f6c330f5b540. Report an issue: GitHub.