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
- Set logs_export_host in the control plane as host:port, e.g. collector.cvc.local:514
- After fixing the value, re-attach or reconfigure the compute so the new spec is fetched
- 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
- Enforce host:port format for logs_export_host at the control plane before it reaches computes
- Unit-test PostgresLogsRsyslogConfig::build for every value shape you ship
- Reject IPv6-without-brackets values at ingestion
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
- Error parsing {remote_endpoint}, expected host:port, got {er
- Invalid address format {remote_endpoint}, expected host:port
- Invalid host
- Invalid port in {remote_endpoint}
- AUDIT_LOGGING_ENDPOINT and AUDIT_LOGGING_TLS_ENDPOINT are bo
AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16).
Data as JSON: /api/errors/1fe77a1bb84c0f7a.
Report an issue: GitHub.