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

  1. Use ?format=pprof (default) or ?format=svg exactly, lowercase
  2. Omit the format parameter if the pprof protobuf output is acceptable
  3. 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

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


AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16). Data as JSON: /api/errors/59f3964c352ebbd5. Report an issue: GitHub.