vectordotdev/vector · critical
unexpected metric
Error message
unexpected metric
What it means
The Datadog traces sink is partitioned by API key and only accepts Trace events. Its Partitioner::partition implementation asserts the event kind: receiving a Metric or Log event is a programming/config error and panics immediately.
Solutions
- Fix the topology so only Trace events reach the datadog traces sink (route explicitly on the event type)
- Replace wildcard ('*') routes with explicit type-scoped routes, or add a filter/route transform checking .message_type or event kind before the sink
- Run `vector validate` / `vector graph` to inspect which sources/transforms feed the sink
- If the events are intended, use the datadog logs sink or metrics sink for those types instead
Example fix
// before (vector.toml style) [sinks.datadog_traces] inputs = ["*"] // after [sinks.datadog_traces] inputs = ["traces_only"] // where 'traces_only' is a route that passes only Trace events
Defensive patterns
Strategy: validation
Validate before calling
// before wiring the sink, assert event kinds on the input path assert!(events.iter().all(|e| matches!(e, Event::Trace(_))), "traces sink received non-trace events");
Type guard
fn only_traces(events: &[Event]) -> bool { events.iter().all(|e| matches!(e, Event::Trace(_))) } Prevention
- Never use wildcard routes into type-specific sinks; route explicitly by event type
- Add a filter/route transform before the sink that drops non-trace events
- Run `vector validate` on the topology and review `vector top`/tap output for misrouted events
- Keep unit tests for sink partitioners fed with representative events of the accepted type only
When it happens
Trigger: An event of type Metric or Log reaches the datadog traces sink — typically via a misconfigured topology where a route or wildcard ('*') sends non-trace events into this sink, or a transform mislabels event types.
Common situations: A wildcard route matching all event types and one branch pointing at the traces sink; pipelines where logs are mistakenly routed to the traces sink; tests constructing the sink with synthetic non-trace events.
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
- Could not build Datadog domain regex
- `duration` should be an i64
- `error` should be an i64
- `parent_id` should be an i64
- registered log schema required
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/a10018e6daad90d6.
Report an issue: GitHub.
Appendix: source
Thrown at src/sinks/datadog/traces/sink.rs:48
pub(crate) struct PartitionKey {
pub(crate) api_key: Option<Arc<str>>,
pub(crate) env: Option<String>,
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"))View on GitHub (pinned to bdb87aeaa4)