vectordotdev/vector · critical

unexpected log

Error message

unexpected log

What it means

The Datadog traces sink's partition function panicked because it received an Event::Log instead of the Event::Trace events it is designed to handle. The sink only supports trace events; any other event type reaching it indicates a topology wiring mistake where a log pipeline was routed into the traces sink. Vector panics deliberately because this is an unrecoverable misconfiguration of the internal event graph.

Solutions

  1. Rewire the topology so only trace events flow into sinks.datadog.traces (fix the inputs list in config)
  2. Insert a filter or route transform that drops non-trace events before the traces sink
  3. If logs must also go to Datadog, add a separate datadog.logs sink and route logs to it

Example fix

// before
[sinks.traces]
type = "datadog_traces"
inputs = ["all_events"]

// after
[sinks.traces]
type = "datadog_traces"
inputs = ["route.trace_events"]
Defensive patterns

Strategy: validation

Validate before calling

// Ensure only trace events reach the sink
fn assert_traces_only(events: &[Event]) -> Result<(), String> {
    if events.iter().any(|e| !matches!(e, Event::Trace(_))) {
        return Err("non-trace events routed to datadog_traces sink".into());
    }
    Ok(())
}

Type guard

fn is_trace(e: &Event) -> bool { matches!(e, Event::Trace(_)) }

Prevention

When it happens

Trigger: Routing a logs source (or a transform emitting logs) into sinks.datadog.traces; a wildcard ('*') or catch-all output feeding the traces sink with mixed event types; a custom transform that does not filter non-trace events before the traces sink.

Common situations: Users configure datadog.traces alongside datadog.logs and accidentally point both at the same sink, or use a broad match like type='*'' in route outputs so logs land in the traces sink.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at src/sinks/datadog/traces/sink.rs:51

    pub(crate) hostname: Option<String>,
    pub(crate) agent_version: Option<String>,
    // Those two last fields are configuration value and not a per-trace/span information, they come from the Datadog
    // trace-agent config directly: https://github.com/DataDog/datadog-agent/blob/0f73a78/pkg/trace/config/config.go#L293-L294
    pub(crate) target_tps: Option<i64>,
    pub(crate) error_tps: Option<i64>,
}

impl Partitioner for EventPartitioner {
    type Item = Event;
    type Key = PartitionKey;

    fn partition(&self, item: &Self::Item) -> Self::Key {
        match item {
            Event::Metric(_) => {
                panic!("unexpected metric");
            }
            Event::Log(_) => {
                panic!("unexpected log");
            }
            Event::Trace(t) => PartitionKey {
                api_key: item.metadata().datadog_api_key(),
                env: t
                    .get(event_path!("env"))
                    .map(|s| s.to_string_lossy().into_owned()),
                hostname: log_schema().host_key().and_then(|key| {
                    t.get((PathPrefix::Event, key))
                        .map(|s| s.to_string_lossy().into_owned())
                }),
                agent_version: t
                    .get(event_path!("agent_version"))
                    .map(|s| s.to_string_lossy().into_owned()),
                target_tps: t
                    .get(event_path!("target_tps"))
                    .and_then(|tps| tps.as_integer()),
                error_tps: t
                    .get(event_path!("error_tps"))

View on GitHub (pinned to bdb87aeaa4)