vectordotdev/vector · error
API key should be only valid ASCII characters
Error message
API key should be only valid ASCII characters
What it means
Datadog metrics requests can override the API key per event; the override string is converted with HeaderValue::from_str, which accepts only visible ASCII. This expect fires when an event-supplied API key contains non-ASCII bytes, control characters (including newlines), or other characters the header grammar rejects.
Source
Thrown at src/sinks/datadog/metrics/service.rs:64
pub content_type: &'static str,
pub content_encoding: &'static str,
pub finalizers: EventFinalizers,
pub metadata: RequestMetadata,
}
impl DatadogMetricsRequest {
/// Converts this request to a `hyper`-compatible request.
///
/// # Errors
///
/// If any of the header names or values are invalid, or if the URI is invalid, an error variant
/// will be returned.
pub fn into_http_request(self, api_key: HeaderValue) -> http::Result<Request<Body>> {
// use the API key from the incoming event if it is provided
let api_key = self.api_key.map_or_else(
|| api_key,
|key| {
HeaderValue::from_str(&key).expect("API key should be only valid ASCII characters")
},
);
let request = Request::post(self.uri)
.header("DD-API-KEY", api_key)
// TODO: The Datadog Agent sends this header to indicate the version of the Go library
// it uses which contains the Protocol Buffers definitions used for the Sketches API.
// We've copypasted the proto file for now -- `proto/ddsketch.rs`, a partial chunk of
// `DataDog/agent-payload/proto/metrics/agent_payload.proto` -- and are thus hardcoding
// the version that we copypasted from.
//
// In the future, we should likely figure out a way to depend on/submodule-ize the
// `agent-payload` repo so we can always have an up-to-date proto definition, and be
// able to programmatically set the version of the repo so we don't need to hardcode
// this header.
.header("DD-Agent-Payload", "4.87.0")
.header(CONTENT_TYPE, self.content_type)
.header(CONTENT_ENCODING, self.content_encoding);
View on GitHub (pinned to 3708c39b12)
Solutions
- Sanitize the event field used for the API key in a remap transform (trim whitespace, assert printable ASCII) before the sink
- Guard with VRL: drop events whose key field fails a printable-ASCII regex
- Drop the per-event override and rely on the sink-level api_key if overrides are not required
- Audit which sources can set the override field and constrain them
Example fix
# before [transforms.pre] type = "remap" source = '.dd_api_key = .tenant_key' # after [transforms.pre] type = "remap" source = '.dd_api_key = replace(string!(.tenant_key), r"\\s", "")'
Defensive patterns
Strategy: validation
Validate before calling
# VRL: validate event-supplied API key before the sink
key = string(.dd_api_key) ?? ""
if !contains(key, " ") && key =~ r'^[\x21-\x7e]+$' {
.dd_api_key = key
} else {
abort
} Prevention
- Constrain which sources can set the per-event API key field
- Strip whitespace in a remap transform upstream of datadog_metrics
- Treat the key field as untrusted input; validate charset like any header
When it happens
Trigger: A datadog_metrics sink with per-event API key overrides where the event field supplying the key contains a newline, trailing whitespace, non-ASCII characters, or quote characters.
Common situations: Keys templated from event fields polluted with whitespace; upstream systems choosing the key from unvalidated data; smart quotes introduced by copy-paste.
Related errors
- `error` should be an i64
- `duration` should be an i64
- `parent_id` should be an i64
- message is required (make sure the "message" semantic meanin
- Env var DD_ORIGIN_PRODUCT must be an unsigned 32 bit integer
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/e519531bc9c8fb8d.
Report an issue: GitHub.