{"record":{"id":"16f0f6c330f5b540","repo":"apache/druid","slug":"failed-to-parse-metrics-and-dimensions","errorCode":null,"errorMessage":"Failed to parse metrics and dimensions","messagePattern":"Failed to parse metrics and dimensions","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions-contrib/opentsdb-emitter/src/main/java/org/apache/druid/emitter/opentsdb/EventConverter.java","lineNumber":123,"sourceCode":"  }\n\n  private Map<String, Set<String>> readMap(ObjectMapper mapper, String metricMapPath)\n  {\n    try {\n      InputStream is;\n      if (Strings.isNullOrEmpty(metricMapPath)) {\n        log.info(\"Using default metric map\");\n        is = this.getClass().getClassLoader().getResourceAsStream(\"defaultMetrics.json\");\n      } else {\n        log.info(\"Using default metric map located at [%s]\", metricMapPath);\n        is = new FileInputStream(new File(metricMapPath));\n      }\n      return mapper.readerFor(new TypeReference<Map<String, Set<String>>>()\n      {\n      }).readValue(is);\n    }\n    catch (IOException e) {\n      throw new ISE(e, \"Failed to parse metrics and dimensions\");\n    }\n  }\n}\n","sourceCodeStart":105,"sourceCodeEnd":127,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-contrib/opentsdb-emitter/src/main/java/org/apache/druid/emitter/opentsdb/EventConverter.java#L105-L127","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Validate the metrics/dimensions file is well-formed YAML/JSON and a map of metric-name -> list of strings","Fix indentation and ensure values are lists, e.g. `my.metric: [host, service]`","Load the file through a YAML linter/parser locally before deploying"],"exampleFix":"// before (bad YAML)\nmetrics:\n  requests: host, service\n// after\nmetrics:\n  requests:\n    - host\n    - service","handlingStrategy":"validation","validationCode":"Map<String, Set<String>> parsed = new Yaml().load(configFile);\nif (parsed == null || parsed.isEmpty()) throw new IllegalArgumentException(\"opentsdb metrics config must be a non-empty map\");\nparsed.values().forEach(v -> { if (!(v instanceof Set || v instanceof List)) throw new IllegalArgumentException(\"values must be lists of dimensions\"); });","typeGuard":null,"tryCatchPattern":"try { new OpentsdbEmitter(config, mapper); } catch (IllegalStateException e) { if (e.getMessage().contains(\"parse metrics\")) { validateConfigFile(path); } }","preventionTips":["Run YAML linting on the opentsdb metrics config in CI","Keep values as YAML lists, never comma-separated strings","Validate the file against the Map<String, Set<String>> schema after edits"],"tags":["java","yaml","emitter","opentsdb"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}