vectordotdev/vector · error

Could not convert duration to JSON

Error message

Could not convert duration to JSON

What it means

ToValue for std::time::Duration serializes the duration with serde_json::to_value and expects success. serde_json::to_value can only fail for non-string-keyed maps or unsupported types, so this panic indicates a serde_json serialization invariant was violated while converting a Duration to a config Value.

Solutions

  1. Check for a custom Serialize implementation for Duration (or a wrapper type) that can fail; make it infallible.
  2. Ensure no serde_json serializer feature flags (e.g. arbitrary_precision mismatches) differ between build units.
  3. Verify no manual ToValue impl produces a non-JSON-serializable intermediate value.
  4. Update serde_json/vector-config to a matching version so Duration serialization behaves as expected.

Example fix

// before
impl Serialize for MyDurationWrapper {
    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> { Err(serde::ser::Error::custom("unsupported")) }
}
// after
impl Serialize for MyDurationWrapper {
    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> { self.as_secs_f64().serialize(s) }
}
Defensive patterns

Strategy: type-guard

Type guard

fn duration_to_value(d: &Duration) -> Option<Value> {
    serde_json::to_value(d).ok()
}

Try / catch

// Rust has no catch; avoid expect by handling Result
let value = serde_json::to_value(duration).unwrap_or_else(|e| {
    eprintln!("duration serialization failed: {e}");
    Value::Null
});

Prevention

When it happens

Trigger: Calling to_value() on a config struct containing a Duration field where serde_json serialization unexpectedly fails (e.g. a custom Serialize impl returning an error, or serialization of a map with non-string keys nested in the duration wrapper).

Common situations: Building config schemas or merging default configs that include Duration fields; rare in practice because Duration serializes deterministically — usually seen when someone adds a custom Serializer/Serializer impl around Duration.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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

Appendix: source

Thrown at lib/vector-config/src/stdlib.rs:501

    fn generate_schema(_: &RefCell<SchemaGenerator>) -> Result<SchemaObject, GenerateError> {
        let mut properties = IndexMap::default();
        properties.insert("secs".into(), generate_number_schema::<u64>());
        properties.insert("nsecs".into(), generate_number_schema::<u32>());

        let mut required = BTreeSet::default();
        required.insert("secs".into());
        required.insert("nsecs".into());

        Ok(crate::schema::generate_struct_schema(
            properties, required, None,
        ))
    }
}

impl ToValue for Duration {
    fn to_value(&self) -> Value {
        serde_json::to_value(self).expect("Could not convert duration to JSON")
    }
}

View on GitHub (pinned to bdb87aeaa4)