neondatabase/neon · error

Invalid host format for Postgres logs export

Error message

Invalid host format for Postgres logs export

What it means

PostgresLogsRsyslogConfig::build received Some(host) from the spec's logs_export_host field, but host.split_once(':') found no colon, so there is no host/port pair to substitute into the rsyslog forwarding template. Unlike parse_audit_syslog_address, this path only requires one colon - no deeper URL validation happens. configure_postgres_logs_export propagates the error (compute.rs uses `?`), failing compute configuration.

Source

Thrown at compute_tools/src/rsyslog.rs:211

impl<'a> PostgresLogsRsyslogConfig<'a> {
    pub fn new(host: Option<&'a str>) -> Self {
        Self { host }
    }

    pub fn build(&self) -> Result<String> {
        match self.host {
            Some(host) => {
                if let Some((target, port)) = host.split_once(":") {
                    Ok(format!(
                        include_str!(
                            "config_template/compute_rsyslog_postgres_export_template.conf"
                        ),
                        logs_export_target = target,
                        logs_export_port = port,
                    ))
                } else {
                    Err(anyhow!("Invalid host format for Postgres logs export"))
                }
            }
            None => Ok("".to_string()),
        }
    }

    fn current_config() -> Result<String> {
        let config_content = match std::fs::read_to_string(POSTGRES_LOGS_CONF_PATH) {
            Ok(c) => c,
            Err(err) if err.kind() == ErrorKind::NotFound => String::new(),
            Err(err) => return Err(err.into()),
        };
        Ok(config_content)
    }
}

/// Writes rsyslogd configuration for Postgres logs export and restarts rsyslog.
pub fn configure_postgres_logs_export(conf: PostgresLogsRsyslogConfig) -> Result<()> {

View on GitHub (pinned to 8f60b04da4)

Solutions

  1. Set logs_export_host in the control plane as host:port, e.g. collector.cvc.local:514
  2. After fixing the value, re-attach or reconfigure the compute so the new spec is fetched
  3. Validate the format at the control plane before it reaches compute_ctl

Example fix

// before
let conf = PostgresLogsRsyslogConfig::new(Some("invalid"));

// after
let conf = PostgresLogsRsyslogConfig::new(Some("collector.cvc.local:514"));
Defensive patterns

Strategy: validation

Validate before calling

// guard the spec field before building the config
let host = match spec.logs_export_host.as_deref() {
    Some(h) if h.split_once(':').is_some() => Some(h),
    other => {
        tracing::warn!("ignoring malformed logs_export_host: {other:?}");
        None
    }
};
let conf = PostgresLogsRsyslogConfig::new(host);

Type guard

fn is_host_port_pair(host: &str) -> bool {
    matches!(host.split_once(':'), Some((h, p)) if !h.is_empty() && p.parse::<u16>().is_ok())
}

Try / catch

match self.host {
    Some(host) if host.split_once(':').is_some() => { /* build template */ }
    Some(host) => return Err(anyhow!("Invalid host format for Postgres logs export: {host}")),
    None => Ok(String::new()),
}

Prevention

When it happens

Trigger: The control-plane spec carries logs_export_host without a colon, e.g. "invalid" or a bare hostname; the unit test test_postgres_logs_config encodes exactly this rejection.

Common situations: Setting the endpoint's log export destination in the console/API to a hostname without a port; unbracketed IPv6 values whose colons are consumed oddly; hand-edited specs.

Related errors


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