{"record":{"id":"883b9efd567d057d","repo":"apache/druid","slug":"failed-to-parse-metric-dimensions-and-types-883b9e","errorCode":null,"errorMessage":"Failed to parse metric dimensions and types","messagePattern":"Failed to parse metric dimensions and types","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions-contrib/statsd-emitter/src/main/java/org/apache/druid/emitter/statsd/DimensionConverter.java","lineNumber":95,"sourceCode":"  }\n\n  private Map<String, StatsDMetric> readMap(ObjectMapper mapper, String dimensionMapPath)\n  {\n    try {\n      InputStream is;\n      if (Strings.isNullOrEmpty(dimensionMapPath)) {\n        log.info(\"Using default metric dimension and types\");\n        is = this.getClass().getClassLoader().getResourceAsStream(\"defaultMetricDimensions.json\");\n      } else {\n        log.info(\"Using metric dimensions at types at [%s]\", dimensionMapPath);\n        is = new FileInputStream(new File(dimensionMapPath));\n      }\n      return mapper.readerFor(new TypeReference<Map<String, StatsDMetric>>()\n      {\n      }).readValue(is);\n    }\n    catch (IOException e) {\n      throw new ISE(e, \"Failed to parse metric dimensions and types\");\n    }\n  }\n}\n","sourceCodeStart":77,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-contrib/statsd-emitter/src/main/java/org/apache/druid/emitter/statsd/DimensionConverter.java#L77-L99","documentation":"StatsDEmitter's DimensionConverter loads a JSON file mapping metric names to StatsDMetric dimensions/types. If Jackson cannot parse the configured file as Map<String, StatsDMetric> (malformed JSON, wrong structure), readMap wraps the IOException in an ISE with this message.","triggerScenarios":"statsd emitter configured with dimensionsFile whose content is invalid JSON, or valid JSON that does not match Map<String, StatsDMetric> (e.g. array at top level, missing metricType fields, wrong types for dimensions).","commonSituations":"Hand-edited dimensions JSON with a trailing comma; file written as a JSON array instead of object; copy-pasted config using snake_case fields not recognized by StatsDMetric; unreadable/garbled file contents.","solutions":["Validate the dimensions JSON: top level must be an object mapping metric name -> {dimensions, metricType}.","Run the file through a JSON linter (jq . dimensions.json) to find syntax errors.","Check that each entry's fields match StatsDMetric's expected property names and types.","Ensure the file path configured points at the intended file, not an HTML error page or empty file."],"exampleFix":"// before\n{\"metric1\": [\"dim1\"]}\n// after\n{\"metric1\": {\"dimensions\": [\"dim1\"], \"metricType\": \"timer\"}}","handlingStrategy":"validation","validationCode":"JsonNode root = new ObjectMapper().readTree(dimensionFile);\nif (!root.isObject()) throw new IllegalArgumentException(\"dimensions file must be a JSON object mapping metric name -> StatsDMetric\");","typeGuard":null,"tryCatchPattern":"try { converter = new DimensionConverter(mapper, dimensionFile); } catch (ISE e) { log.error(\"Invalid statsd dimensions file %s: %s\", dimensionFile, e.getMessage()); throw e; }","preventionTips":["Validate dimensions JSON with jq or a linter before deploying.","Keep the schema: object of {metricName: {dimensions: [...], metricType: \"...\"}}.","Avoid hand-edits without re-validating; keep the file in version control.","Confirm the configured path points to real JSON, not an error page or empty file."],"tags":["java","druid","statsd","json","config"],"backgroundTag":"json-parse-error","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}