{"record":{"id":"9b979f70c241daf4","repo":"apache/druid","slug":"value-of-nan-is-not-allowed","errorCode":null,"errorMessage":"Value of NaN is not allowed!","messagePattern":"Value of NaN is not allowed!","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/emitter/service/ServiceMetricEvent.java","lineNumber":195,"sourceCode":"      if (dim == null) {\n        throw new IAE(\"Dimension name cannot be null\");\n      } else if (value == null) {\n        throw new IAE(\"Value of dimension[%s] cannot be null\", dim);\n      }\n\n      userDims.put(dim, value);\n      return this;\n    }\n\n    public Object getDimension(String dim)\n    {\n      return userDims.get(dim);\n    }\n\n    public Builder setMetric(String metric, Number value)\n    {\n      if (Double.isNaN(value.doubleValue())) {\n        throw new ISE(\"Value of NaN is not allowed!\");\n      }\n      if (Double.isInfinite(value.doubleValue())) {\n        throw new ISE(\"Value of Infinite is not allowed!\");\n      }\n\n      this.metric = metric;\n      this.value = value;\n      return this;\n    }\n\n    public Builder setCreatedTime(DateTime createdTime)\n    {\n      this.createdTime = createdTime;\n      return this;\n    }\n\n    @Override\n    public ServiceMetricEvent build(ImmutableMap<String, String> serviceDimensions)","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/emitter/service/ServiceMetricEvent.java#L177-L213","documentation":"ServiceMetricEvent.Builder.setMetric rejects NaN values with ISE. Metric values must be real finite numbers because NaN cannot be serialized/aggregated meaningfully by metrics consumers (e.g. graphite, statsd, dimensional store). Throwing keeps NaN out of the metrics pipeline.","triggerScenarios":"Calling setMetric(name, value) where value.doubleValue() is NaN — typically from a 0.0/0.0 division, sqrt of a negative, or parsing a non-numeric string into a double.","commonSituations":"Custom Druid monitors computing ratios/averages over empty collections; emitting timing metrics when no samples were taken; ingestion stats divided by zero rows.","solutions":["Fix the computation producing NaN (guard against division by zero / empty inputs).","Sanitize before emitting: if (Double.isNaN(v) || Double.isInfinite(v)) skip or substitute 0/null policy value.","Emit an explicit absence (don't call setMetric) and log a warning so missing data is distinguishable from zero.","Check monitor code ordering — a metric computed before its inputs exist often yields NaN."],"exampleFix":"// before\ndouble avg = total / count; // count == 0 -> NaN\nbuilder.setMetric(\"task/avg/time\", avg); // ISE\n// after\ndouble avg = count > 0 ? total / count : 0.0;\nif (!Double.isNaN(avg) && !Double.isInfinite(avg)) {\n  builder.setMetric(\"task/avg/time\", avg);\n}","handlingStrategy":"validation","validationCode":"double v = metricValue.doubleValue();\nif (Double.isNaN(v)) { return; /* or substitute policy value */ }\nbuilder.setMetric(metricName, metricValue);","typeGuard":null,"tryCatchPattern":"try {\n  builder.setMetric(name, value);\n} catch (IllegalStateException e) {\n  log.warn(\"Skipping non-finite metric [%s]\", name);\n}","preventionTips":["Guard divisions against zero/empty inputs before computing the metric","Centralize metric emission in a helper that filters NaN/Infinite","Distinguish 'no data' (skip emit) from 0"],"tags":["metrics","nan","validation","illegal-state"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}