neondatabase/neon · error

Invalid address format {remote_endpoint}, expected host:port

Error message

Invalid address format {remote_endpoint}, expected host:port

What it means

The synthetic http:// URL parsed, but contained components a bare host:port must not have: a path, query, fragment, username or password. The code checks url.scheme() == "http" && path == "/" && query/fragment/username/password are all empty and rejects anything else. Note the check runs after successful parsing, so this is a semantic-format rejection, not a URL syntax error.

Source

Thrown at compute_tools/src/rsyslog.rs:113

    } else {
        tls = "false".to_string();
        remote_plain_endpoint
    };
    // Urlify the remote_endpoint, so parsing can be done with url::Url.
    let url_str = format!("http://{remote_endpoint}");
    let url = Url::parse(&url_str).map_err(|err| {
        anyhow!("Error parsing {remote_endpoint}, expected host:port, got {err:?}")
    })?;

    let is_valid = url.scheme() == "http"
        && url.path() == "/"
        && url.query().is_none()
        && url.fragment().is_none()
        && url.username() == ""
        && url.password().is_none();

    if !is_valid {
        return Err(anyhow!(
            "Invalid address format {remote_endpoint}, expected host:port"
        ));
    }
    let host = match url.host() {
        Some(Host::Domain(h)) if hostname_validator::is_valid(h) => h.to_string(),
        Some(Host::Ipv4(ip4)) => ip4.to_string(),
        Some(Host::Ipv6(ip6)) => ip6.to_string(),
        _ => return Err(anyhow!("Invalid host")),
    };
    let port = url
        .port()
        .ok_or_else(|| anyhow!("Invalid port in {remote_endpoint}"))?;

    Ok((host, port, tls))
}

fn generate_audit_rsyslog_config(
    log_directory: String,

View on GitHub (pinned to 8f60b04da4)

Solutions

  1. Strip scheme, path, query, fragment and userinfo - supply only host:port
  2. If the value came from a full URL, extract just the authority before configuring audit logging
  3. Add a startup assertion rejecting '/', '?', '#', '@', '://' in endpoint values

Example fix

// before
parse_audit_syslog_address("collector.host.tld:514/path?x=1", "");

// after
parse_audit_syslog_address("collector.host.tld:514", "");
Defensive patterns

Strategy: validation

Validate before calling

// strip URL decorations down to a bare host:port authority
let endpoint = full_url
    .trim_start_matches("http://")
    .trim_start_matches("https://")
    .split('/').next().unwrap_or("")
    .split('?').next().unwrap_or("")
    .split('#').next().unwrap_or("");
assert!(endpoint.split(':').count() <= 2 || endpoint.starts_with('['), "expected host:port");

Type guard

fn is_bare_host_port(endpoint: &str) -> bool {
    !endpoint.contains('/') && !endpoint.contains('?') && !endpoint.contains('#')
        && !endpoint.contains('@') && !endpoint.contains("://")
        && endpoint.rsplit_once(':').is_some()
}

Try / catch

let is_valid = url.scheme() == "http" && url.path() == "/" && url.query().is_none()
    && url.fragment().is_none() && url.username().is_empty() && url.password().is_none();
if !is_valid {
    return Err(anyhow!("Invalid address format {remote_endpoint}, expected host:port"));
}

Prevention

When it happens

Trigger: Endpoint values like 'collector.host:514/path', 'user@collector.host:514', 'user:pass@collector.host:514', or 'collector.host:514?q=1' pass Url::parse but embed forbidden components.

Common situations: Paste-in values copied from full http:// collector URLs; endpoints documented with auth userinfo; trailing slashes added by convention.

Related errors


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