{"record":{"id":"f3b1c0b8e9694b90","repo":"jdx/mise","slug":"remote-host-port-must-be-greater-than-zero","errorCode":null,"errorMessage":"remote host '{}' port must be greater than zero","messagePattern":"remote host '(.+?)' port must be greater than zero","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/remote.rs","lineNumber":326,"sourceCode":"\n    pub(crate) fn destination(&self) -> String {\n        match &self.user {\n            Some(user) => format!(\"{user}@{}\", self.host),\n            None => self.host.clone(),\n        }\n    }\n\n    fn validate(&self) -> Result<()> {\n        self.validate_with_source(true)\n    }\n\n    fn validate_with_source(&self, archive: bool) -> Result<()> {\n        validate_ssh_atom(\"host\", &self.host)?;\n        if let Some(user) = &self.user {\n            validate_ssh_atom(\"user\", user)?;\n        }\n        if self.port == Some(0) {\n            bail!(\"remote host '{}' port must be greater than zero\", self.name);\n        }\n        if archive && !self.source.is_dir() {\n            bail!(\n                \"remote host '{}' source is not a directory: {}\",\n                self.name,\n                self.source.display()\n            );\n        }\n        if archive && !self.copy_links {\n            for link in &self.copy_link {\n                validate_copy_link(&self.source, link).wrap_err_with(|| {\n                    format!(\"remote host '{}' has invalid copy_link\", self.name)\n                })?;\n            }\n        }\n        if let Some(identity) = &self.identity_file\n            && !identity.is_file()\n        {","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/remote.rs#L308-L344","documentation":"Thrown by `RemoteHostConfig::validate_with_source` when a remote backup/archive host entry has `port = 0`. A TCP port of zero is not a usable connection port, so mise rejects the configuration up front rather than failing later during SSH/rsync. The host name is included in the message to identify which entry is invalid.","triggerScenarios":"Defining a remote host in mise.toml with `port = 0` (typically a placeholder or parse mistake) and then calling `validate` or `apply_overrides` — e.g. when running a remote backup or archive operation.","commonSituations":"Copy-pasted config where the port was left at 0; a templating expression that evaluated to 0; misunderstanding that 0 means 'default port' (it does not — omit the port field instead).","solutions":["Set the host's `port` to a valid port (1–65535), e.g. 22 for SSH","Remove the `port` field entirely to use SSH's default port","Check any template/env substitution that produced 0 for the port"],"exampleFix":"// before (mise.toml)\n[[remote_backup.hosts]]\nname = \"prod\"\nhost = \"prod.example.com\"\nport = 0\n// after\n[[remote_backup.hosts]]\nname = \"prod\"\nhost = \"prod.example.com\"\nport = 22","handlingStrategy":"validation","validationCode":"fn valid_port(host: &RemoteHostConfig) -> bool {\n    host.port.map(|p| p > 0 && p <= 65535).unwrap_or(true)\n}","typeGuard":"fn port_is_valid(p: Option<u16>) -> bool {\n    matches!(p, None | Some(1..=65535))\n}","tryCatchPattern":null,"preventionTips":["Omit the `port` field instead of using 0 for the default","Validate host entries (ports in 1–65535) when generating config from templates","Review port values after any templating/substitution change"],"tags":["remote","ssh","config-validation","port"],"backgroundTag":"value-out-of-range","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}