neondatabase/neon · critical

AUDIT_LOGGING_ENDPOINT and AUDIT_LOGGING_TLS_ENDPOINT are bo

Error message

AUDIT_LOGGING_ENDPOINT and AUDIT_LOGGING_TLS_ENDPOINT are both empty

What it means

compute_ctl only sets up remote compliance audit logging when a spec demands it (audit_log_level Hipaa/Extended/Full). It reads the destination from the AUDIT_LOGGING_ENDPOINT or AUDIT_LOGGING_TLS_ENDPOINT environment variables; if both are empty/absent it bails because there is nowhere to ship the audit trail. Deployment env and spec must agree.

Source

Thrown at compute_tools/src/compute.rs:958

            let _handle = tokio::spawn(async move {
                if let Err(err) = local_proxy::configure(&local_proxy) {
                    error!("error while configuring local_proxy: {err:?}");
                    // Continue with the startup anyway
                }
            });
        }

        // Configure and start rsyslog for compliance audit logging
        match pspec.spec.audit_log_level {
            ComputeAudit::Hipaa | ComputeAudit::Extended | ComputeAudit::Full => {
                let remote_tls_endpoint =
                    std::env::var("AUDIT_LOGGING_TLS_ENDPOINT").unwrap_or("".to_string());
                let remote_plain_endpoint =
                    std::env::var("AUDIT_LOGGING_ENDPOINT").unwrap_or("".to_string());

                if remote_plain_endpoint.is_empty() && remote_tls_endpoint.is_empty() {
                    anyhow::bail!(
                        "AUDIT_LOGGING_ENDPOINT and AUDIT_LOGGING_TLS_ENDPOINT are both empty"
                    );
                }

                let log_directory_path = Path::new(&self.params.pgdata).join("log");
                let log_directory_path = log_directory_path.to_string_lossy().to_string();

                // Add project_id,endpoint_id to identify the logs.
                //
                // These ids are passed from cplane,
                let endpoint_id = pspec.spec.endpoint_id.as_deref().unwrap_or("");
                let project_id = pspec.spec.project_id.as_deref().unwrap_or("");

                configure_audit_rsyslog(
                    log_directory_path.clone(),
                    endpoint_id,
                    project_id,
                    &remote_plain_endpoint,

View on GitHub (pinned to 8f60b04da4)

Solutions

  1. Set AUDIT_LOGGING_ENDPOINT (plaintext) or AUDIT_LOGGING_TLS_ENDPOINT (TLS) in the compute_ctl container environment and restart the endpoint
  2. If audit logging is not actually required, lower spec.audit_log_level so the rsyslog path is not taken
  3. Add a deployment-time assertion: audit levels imply at least one endpoint variable

Example fix

# before: spec.audit_log_level = "Hipaa", env empty -> bail
# after
AUDIT_LOGGING_TLS_ENDPOINT=audit.example.com:6514 compute_ctl run ...
Defensive patterns

Strategy: validation

Validate before calling

// Before launching a compute with an audit spec, verify its env
fn audit_env_ok(level: ComputeAudit) -> bool {
    let needs_remote = matches!(level, ComputeAudit::Hipaa | ComputeAudit::Extended | ComputeAudit::Full);
    !needs_remote
        || !std::env::var("AUDIT_LOGGING_ENDPOINT").unwrap_or_default().is_empty()
        || !std::env::var("AUDIT_LOGGING_TLS_ENDPOINT").unwrap_or_default().is_empty()
}

Try / catch

// Fail with an actionable message at deploy time rather than at compute start
if !audit_env_ok(spec.audit_log_level) {
    anyhow::bail!("audit level {:?} requires AUDIT_LOGGING_ENDPOINT or AUDIT_LOGGING_TLS_ENDPOINT", spec.audit_log_level);
}

Prevention

When it happens

Trigger: A ComputeSpec with spec.audit_log_level in {Hipaa, Extended, Full} reaches start_compute while the compute_ctl process environment has neither AUDIT_LOGGING_ENDPOINT nor AUDIT_LOGGING_TLS_ENDPOINT set (both default to "").

Common situations: Enabling HIPAA/audit levels on a project whose compute pods lack the env vars; local/dev runs of compute_ctl with an audit spec; infra migration where the env vars were dropped from the pod template; misnamed variable (e.g. AUDIT_LOG_ENDPOINT).

Related errors


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