vectordotdev/vector · error

JSON doesn't allow NaNs

Error message

JSON doesn't allow NaNs

What it means

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.

Solutions

  1. Fix the upstream producer so the GELF `line` field is a plain finite integer
  2. Sanitize/drop the `line` field before feeding the payload to the GELF decoder
  3. Patch/upgrade the deserializer so NaN cannot reach the codec

Example fix

// before (in producer, Rust-like pseudocode)
json!({ "line": f64::NAN, "short_message": "x" })
// after
let line = if line.is_finite() { line } else { 0.0 };
json!({ "line": line, "short_message": "x" })
Defensive patterns

Strategy: validation

Validate before calling

// Rust, before feeding GELF JSON to the decoder
if let Some(line) = payload.get("line") {
    let v = line.as_f64().expect("line must be numeric");
    assert!(v.is_finite() && v.fract() == 0.0, "GELF line must be a finite integer, got {v}");
}

Type guard

fn is_valid_gelf_line(v: &serde_json::Value) -> bool {
    v.as_f64().map(|f| f.is_finite() && f.fract() == 0.0).unwrap_or(false)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/c178be9fd81c5502. Report an issue: GitHub.

Appendix: source

Thrown at lib/codecs/src/decoding/format/gelf.rs:171

        if let Some(timestamp_key) = log_schema().timestamp_key_target_path() {
            if let Some(timestamp) = parsed.timestamp {
                log.insert(timestamp_key, timestamp);
                // per GELF spec- add timestamp if not provided
            } else {
                log.insert(timestamp_key, Utc::now());
            }
        }

        if let Some(level) = parsed.level {
            log.insert(&GELF_TARGET_PATHS.level, level);
        }
        if let Some(facility) = &parsed.facility {
            log.insert(&GELF_TARGET_PATHS.facility, facility.to_string());
        }
        if let Some(line) = parsed.line {
            log.insert(
                &GELF_TARGET_PATHS.line,
                Value::Float(ordered_float::NotNan::new(line).expect("JSON doesn't allow NaNs")),
            );
        }
        if let Some(file) = &parsed.file {
            log.insert(&GELF_TARGET_PATHS.file, file.to_string());
        }

        if let Some(add) = &parsed.additional_fields {
            for (key, val) in add.iter() {
                // per GELF spec, filter out _id
                if key == "_id" {
                    continue;
                }
                // per GELF spec, Additional field names must be prefixed with an underscore
                if self.validation == ValidationMode::Strict && !key.starts_with('_') {
                    return Err(format!(
                        "'{key}' field is invalid. \
                                       Additional field names must be prefixed with an underscore."
                    )

View on GitHub (pinned to bdb87aeaa4)