{"record":{"id":"c178be9fd81c5502","repo":"vectordotdev/vector","slug":"json-doesn-t-allow-nans","errorCode":null,"errorMessage":"JSON doesn't allow NaNs","messagePattern":"JSON doesn't allow NaNs","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/codecs/src/decoding/format/gelf.rs","lineNumber":171,"sourceCode":"        if let Some(timestamp_key) = log_schema().timestamp_key_target_path() {\n            if let Some(timestamp) = parsed.timestamp {\n                log.insert(timestamp_key, timestamp);\n                // per GELF spec- add timestamp if not provided\n            } else {\n                log.insert(timestamp_key, Utc::now());\n            }\n        }\n\n        if let Some(level) = parsed.level {\n            log.insert(&GELF_TARGET_PATHS.level, level);\n        }\n        if let Some(facility) = &parsed.facility {\n            log.insert(&GELF_TARGET_PATHS.facility, facility.to_string());\n        }\n        if let Some(line) = parsed.line {\n            log.insert(\n                &GELF_TARGET_PATHS.line,\n                Value::Float(ordered_float::NotNan::new(line).expect(\"JSON doesn't allow NaNs\")),\n            );\n        }\n        if let Some(file) = &parsed.file {\n            log.insert(&GELF_TARGET_PATHS.file, file.to_string());\n        }\n\n        if let Some(add) = &parsed.additional_fields {\n            for (key, val) in add.iter() {\n                // per GELF spec, filter out _id\n                if key == \"_id\" {\n                    continue;\n                }\n                // per GELF spec, Additional field names must be prefixed with an underscore\n                if self.validation == ValidationMode::Strict && !key.starts_with('_') {\n                    return Err(format!(\n                        \"'{key}' field is invalid. \\\n                                       Additional field names must be prefixed with an underscore.\"\n                    )","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/lib/codecs/src/decoding/format/gelf.rs#L153-L189","documentation":"Vector's GELF decoder converts the GELF `line` field (source file line number) into a `Value::Float` using `ordered_float::NotNan::new`, which panics if the parsed f64 is NaN. JSON cannot represent NaN, so the codec refuses to store one as an event value. This is a deliberate invariant guard: an event field must be serializable back to JSON.","triggerScenarios":"Calling `parse` (via `message_to_event`) on a GELF payload whose `line` field decodes to NaN — practically only when `line` was computed from arithmetic that produced NaN, or a custom/patched deserializer let a NaN literal through.","commonSituations":"Producers emitting non-numeric or synthetic `line` values; fuzzing or custom GELF parsers; hand-crafted GELF JSON produced by tools that allow non-standard NaN literals.","solutions":["Fix the upstream producer so the GELF `line` field is a plain finite integer","Sanitize/drop the `line` field before feeding the payload to the GELF decoder","Patch/upgrade the deserializer so NaN cannot reach the codec"],"exampleFix":"// before (in producer, Rust-like pseudocode)\njson!({ \"line\": f64::NAN, \"short_message\": \"x\" })\n// after\nlet line = if line.is_finite() { line } else { 0.0 };\njson!({ \"line\": line, \"short_message\": \"x\" })","handlingStrategy":"validation","validationCode":"// Rust, before feeding GELF JSON to the decoder\nif let Some(line) = payload.get(\"line\") {\n    let v = line.as_f64().expect(\"line must be numeric\");\n    assert!(v.is_finite() && v.fract() == 0.0, \"GELF line must be a finite integer, got {v}\");\n}","typeGuard":"fn is_valid_gelf_line(v: &serde_json::Value) -> bool {\n    v.as_f64().map(|f| f.is_finite() && f.fract() == 0.0).unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Ensure all GELF producers emit `line` as a plain finite integer","Sanitize or drop non-finite `line` values at ingestion","Never compute `line` with arithmetic that can produce NaN"],"tags":["rust","gelf","json","nan","decoding"],"backgroundTag":"value-out-of-range","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}