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
- Set AUDIT_LOGGING_ENDPOINT (plaintext) or AUDIT_LOGGING_TLS_ENDPOINT (TLS) in the compute_ctl container environment and restart the endpoint
- If audit logging is not actually required, lower spec.audit_log_level so the rsyslog path is not taken
- 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
- Encode the rule in deployment manifests: any pod that may run Hipaa/Extended/Full specs gets both env vars
- Add a preflight check script in the image entrypoint for audit env vars
- Include a smoke test that boots a Full-audit compute in CI with the env vars set
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
- pageserver connection information should be provided
- safekeeper connstrings should be provided
- tenant id should be provided
- timeline id should be provided
- postgres --sync-safekeepers exited with non-zero status: {}.
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/e5f0b9e2a12225d4.
Report an issue: GitHub.