linera-io/linera-protocol · error

Failed to find parse port {port_str} for {s}. {parse_error}

Error message

Failed to find parse port {port_str} for {s}. {parse_error}

What it means

After reading hostname and port tokens from a scylladb tcp segment, from_str parses the port with NonZeroU16::from_str. This error means the port token exists but is not a valid nonzero u16 — zero, negative, non-numeric, out of range, or containing trailing characters.

Source

Thrown at linera-storage-runtime/src/storage_config.rs:194

        }
        #[cfg(feature = "scylladb")]
        if let Some(s) = input.strip_prefix(SCYLLA_DB) {
            let mut uri: Option<String> = None;
            let mut namespace: Option<String> = None;
            let parse_error: &'static str = "Correct format is tcp:db_hostname:port.";
            if !s.is_empty() {
                let mut parts = s.split(':');
                while let Some(part) = parts.next() {
                    match part {
                        "tcp" => {
                            let address = parts.next().ok_or_else(|| {
                                anyhow!("Failed to find address for {s}. {parse_error}")
                            })?;
                            let port_str = parts.next().ok_or_else(|| {
                                anyhow!("Failed to find port for {s}. {parse_error}")
                            })?;
                            let port = NonZeroU16::from_str(port_str).map_err(|_| {
                                anyhow!(
                                    "Failed to find parse port {port_str} for {s}. {parse_error}",
                                )
                            })?;
                            if uri.is_some() {
                                bail!("The uri has already been assigned");
                            }
                            uri = Some(format!("{address}:{port}"));
                        }
                        _ if part.starts_with("table") => {
                            if namespace.is_some() {
                                bail!("The namespace has already been assigned");
                            }
                            namespace = Some(part.to_string());
                        }
                        _ => {
                            bail!("the entry \"{part}\" is not matching");
                        }
                    }

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Use a plain integer between 1 and 65535 for the port, e.g. 9042 (the ScyllaDB default)
  2. Check for stray characters around an interpolated port variable: --storage "scylladb:tcp:host:${PORT}" with PORT='9042 ' fails
  3. Do not use 0 — zero ports are rejected by design

Example fix

# before
--storage scylladb:tcp:host:0
# after
--storage scylladb:tcp:host:9042
Defensive patterns

Strategy: validation

Validate before calling

// Rust: pre-validate port tokens
use std::num::NonZeroU16;

fn ports_are_valid(s: &str) -> bool {
    let mut parts = s.split(':');
    while let Some(part) = parts.next() {
        if part == "tcp" {
            let _addr = parts.next().unwrap_or("");
            let port = parts.next().unwrap_or("");
            if NonZeroU16::from_str(port).is_err() { return false; }
        }
    }
    true
}

Type guard

fn is_nonzero_u16(s: &str) -> bool { std::num::NonZeroU16::from_str(s).is_ok() }

Try / catch

let port = NonZeroU16::from_str(port_str)
    .with_context(|| format!("port {port_str:?} in {s:?} must be 1..=65535"))?;

Prevention

When it happens

Trigger: --storage 'scylladb:tcp:host:0', 'scylladb:tcp:host:9042x', 'scylladb:tcp:host:nine' or a port above 65535. Any of these fails the NonZeroU16 parse.

Common situations: Port 0 used as a placeholder; extra characters glued to the port by shell interpolation (e.g. $PORT with a trailing space or newline); IPv6-style colons confusing the ':'-split parser.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/32b96e8f1bf04abd. Report an issue: GitHub.