neondatabase/neon · warning · ApiError
invalid format {format}
Error message
invalid format {format} What it means
Returned as HTTP 400 BadRequest by profile_cpu_handler (the /profile/cpu debugging endpoint in neon's http-utils) when the optional format query parameter is present but is not one of the accepted values 'pprof' or 'svg'. The parameter is matched exactly (case-sensitive), and omitting it entirely is valid (defaults to pprof).
Source
Thrown at libs/http-utils/src/endpoint.rs:379
}
});
Ok(response)
}
/// Generates CPU profiles.
pub async fn profile_cpu_handler(req: Request<Body>) -> Result<Response<Body>, ApiError> {
enum Format {
Pprof,
Svg,
}
// Parameters.
let format = match get_query_param(&req, "format")?.as_deref() {
None => Format::Pprof,
Some("pprof") => Format::Pprof,
Some("svg") => Format::Svg,
Some(format) => return Err(ApiError::BadRequest(anyhow!("invalid format {format}"))),
};
let seconds = match parse_query_param(&req, "seconds")? {
None => 5,
Some(seconds @ 1..=60) => seconds,
Some(_) => return Err(ApiError::BadRequest(anyhow!("duration must be 1-60 secs"))),
};
let frequency_hz = match parse_query_param(&req, "frequency")? {
None => 99,
Some(1001..) => return Err(ApiError::BadRequest(anyhow!("frequency must be <=1000 Hz"))),
Some(frequency) => frequency,
};
let force: bool = parse_query_param(&req, "force")?.unwrap_or_default();
// Take the profile.
static PROFILE_LOCK: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
static PROFILE_CANCEL: Lazy<Notify> = Lazy::new(Notify::new);
let report = {View on GitHub (pinned to 8f60b04da4)
Solutions
- Use ?format=pprof (default) or ?format=svg exactly, lowercase
- Omit the format parameter if the pprof protobuf output is acceptable
- Check for URL-encoding mistakes that alter the value (e.g. svg%21)
Example fix
# before curl 'http://localhost:9898/profile/cpu?format=flamegraph' # 400 invalid format # after curl 'http://localhost:9898/profile/cpu?format=svg'
Defensive patterns
Strategy: validation
Validate before calling
# Validate before scraping:
format="${FORMAT:-pprof}"
[ "$format" = pprof ] || [ "$format" = svg ] || { echo "bad format"; exit 1; }
curl "http://localhost:9898/profile/cpu?format=$format" Type guard
isPprofFormat(fmt) { return fmt === "pprof" || fmt === "svg"; } Prevention
- Pin scrape configs to the documented lowercase values
- Default to omitting format when pprof is acceptable
- Centralize endpoint URLs in one config to keep values consistent across tools
When it happens
Trigger: GET /profile/cpu?format=json, ?format=SVG, or ?format=pprof%2Bgzip — any format value other than exactly 'pprof' or 'svg' returns this 400.
Common situations: Grafana/pyroscope scrape config changed to request a new format; typo or uppercase value in the format param; tooling assuming flamegraph or json is supported.
Related errors
- duration must be 1-60 secs
- frequency must be <=1000 Hz
- heap profiling not enabled
- Cannot manage failpoints because neon was compiled without f
- Failed to configure failpoints: {err_msg}
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/59f3964c352ebbd5.
Report an issue: GitHub.