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
- 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
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
- 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
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
- Buffered payload limit of
- Could not convert concurrency to JSON
- Could not convert HTTP status code to JSON
- Could not convert number to JSON
- Could not convert time zone to JSON
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)