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
- Rewire the topology so only trace events flow into sinks.datadog.traces (fix the inputs list in config)
- Insert a filter or route transform that drops non-trace events before the traces sink
- 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
- Never point sinks.datadog.traces at wildcard or mixed-event outputs
- Route mixed streams through a route transform with a trace-only branch
- Run vector validate before deploying topology changes
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
- `duration` should be an i64
- `error` should be an i64
- join error or bad poll
- `parent_id` should be an i64
- Pausing unknown sink from fanout
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)