neondatabase/neon · warning · ApiError

Cannot manage failpoints because neon was compiled without f

Error message

Cannot manage failpoints because neon was compiled without failpoints support

What it means

Returned as HTTP 400 BadRequest by failpoints_handler in neon's http-utils when the binary was compiled without failpoints support: fail::has_failpoints() is false because the failpoints crate was compiled with its no-op configuration. The /failpoints management endpoint exists in every build, but only builds with the failpoints cargo feature actually embed failpoint instrumentation, so test/chaos scripts hitting the endpoint on a production build get this error.

Source

Thrown at libs/http-utils/src/failpoints.rs:28

/// Information for configuring a single fail point
#[derive(Debug, Serialize, Deserialize)]
pub struct FailpointConfig {
    /// Name of the fail point
    pub name: String,
    /// List of actions to take, using the format described in `fail::cfg`
    ///
    /// We also support `actions = "exit"` to cause the fail point to immediately exit.
    pub actions: String,
}

/// Configure failpoints through http.
pub async fn failpoints_handler(
    mut request: Request<Body>,
    _cancel: CancellationToken,
) -> Result<Response<Body>, ApiError> {
    if !fail::has_failpoints() {
        return Err(ApiError::BadRequest(anyhow::anyhow!(
            "Cannot manage failpoints because neon was compiled without failpoints support"
        )));
    }

    let failpoints: ConfigureFailpointsRequest = json_request(&mut request).await?;
    for fp in failpoints {
        tracing::info!("cfg failpoint: {} {}", fp.name, fp.actions);

        // We recognize one extra "action" that's not natively recognized
        // by the failpoints crate: exit, to immediately kill the process
        let cfg_result = apply_failpoint(&fp.name, &fp.actions);

        if let Err(err_msg) = cfg_result {
            return Err(ApiError::BadRequest(anyhow::anyhow!(
                "Failed to configure failpoints: {err_msg}"
            )));
        }
    }

View on GitHub (pinned to 8f60b04da4)

Solutions

  1. Rebuild the target service with failpoints enabled, e.g. cargo build --features failpoints (or the neon-specific testing profile that turns it on)
  2. Point the failpoint test at a binary that was compiled with the feature (CI's test builds always are)
  3. If you cannot rebuild, remove the failpoint-configuration step from the scenario

Example fix

# before
cargo build -p neon_pageserver        # no failpoints feature
curl -X POST localhost:9898/failpoints ...   # 400: compiled without failpoints support

# after
cargo build -p neon_pageserver --features failpoints
curl -X POST localhost:9898/failpoints -d '[{"name":"persistence-after-s3-sync","actions":"return"}]'
Defensive patterns

Strategy: validation

Validate before calling

# Skip failpoint setup on builds without support:
if curl -sf -X POST localhost:9898/failpoints -H 'Content-Type: application/json' \
     -d '[]' >/dev/null 2>&1; then
  apply_failpoints
else
  echo "failpoints not compiled in; rebuild with --features failpoints"
fi

Try / catch

# Treat 400 'compiled without failpoints support' as a skip, not a failure:
status=$(curl -s -o resp.txt -w '%{http_code}' -X POST localhost:9898/failpoints -d @fp.json)
if [ "$status" = 400 ] && grep -q 'without failpoints support' resp.txt; then
  exit 0  # capability missing; not a test failure
fi

Prevention

When it happens

Trigger: POST /failpoints with a ConfigureFailpointsRequest body against a neon service binary compiled without --features failpoints; the handler rejects the request before parsing or applying any failpoint configuration.

Common situations: Running chaos/test scripts designed for CI builds against locally built or release binaries; forgetting to enable the failpoints feature in a custom build; CI image rebuilds that dropped the feature flag.

Related errors


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