headroomlabs-ai/headroom · warning
metrics response build error: {e}
Error message
metrics response build error: {e} What it means
Building the 200 OK /metrics Response object failed after successful encoding (setting status/header/body on http::Response). This is a can't-happen branch — the response is fully static except for the encoded buffer — so it exists only as an unwrap_or_else guard, returning 500 with this message.
Source
Thrown at crates/headroom-proxy/src/observability/prometheus.rs:286
if let Err(e) = encoder.encode(&metric_families, &mut buffer) {
tracing::error!(
event = "metrics_encode_failed",
error = %e,
"failed to encode Prometheus metrics scrape"
);
return Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from(format!("metrics encode error: {e}")))
.expect("static error response");
}
Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, encoder.format_type())
.body(Body::from(buffer))
.unwrap_or_else(|e| {
Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from(format!("metrics response build error: {e}")))
.expect("static error response")
})
}
#[cfg(test)]
mod tests {
use super::*;
/// Helper: render the registry to a String for assertions.
fn scrape() -> String {
let mf = registry().gather();
let encoder = TextEncoder::new();
let mut buf = Vec::new();
encoder.encode(&mf, &mut buf).expect("encode");
String::from_utf8(buf).expect("utf8")
}
#[test]View on GitHub (pinned to 322425c43b)
Solutions
- If it fires, capture the metrics_response_build_error body — it embeds the underlying http::Error.
- Check the prometheus crate version's format_type() string (should be 'text/plain; version=0.0.4' or similar) against http::HeaderValue rules.
- Downgrade/pin the prometheus crate to a version whose format string is known-good.
Defensive patterns
Strategy: try-catch
Prevention
- Pin the prometheus crate version in Cargo.lock.
- Monitor for this message in logs — it's effectively an invariant trip, report it upstream if seen.
When it happens
Trigger: http::Response::builder rejecting the header value (encoder.format_type() returning something http::HeaderValue refuses) — effectively only possible via a corrupted/changed encoder format string; otherwise unreachable.
Common situations: A prometheus-crate version change to format_type() output that no longer parses as a header value; memory corruption; in practice this should never fire.
Related errors
- metrics encode error: {e}
- upstream request failed: {0}
- invalid upstream URL: {0}
- bedrock_upstream_exception
- bedrock_eventstream_missing_event_type
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/5727eadbb1aa740d.
Report an issue: GitHub.