{"record":{"id":"bee428efa134ac2c","repo":"n0-computer/iroh","slug":"invalid-transport-configuration","errorCode":null,"errorMessage":"Invalid transport configuration","messagePattern":"Invalid transport configuration","errorType":"validation","errorClass":"BindError","httpStatus":null,"severity":"error","filePath":"iroh/src/socket.rs","lineNumber":902,"sourceCode":"            hooks,\n            path_selector,\n            portmapper_config,\n            net_report_config,\n            static_config,\n            configured_addrs,\n        } = opts;\n\n        let address_lookup = address_lookup::AddressLookupServices::default();\n        let port_mapper = portmapper::create_client(&portmapper_config);\n\n        let relay_transport_configs: Vec<_> = transport_configs\n            .iter()\n            .filter(|t| matches!(t, TransportConfig::Relay { .. }))\n            .collect();\n\n        // Currently we only support a single relay transport\n        if relay_transport_configs.len() > 1 {\n            bail!(BindError::InvalidTransportConfig);\n        }\n        let relay_map = relay_transport_configs\n            .iter()\n            .filter_map(|t| {\n                #[allow(irrefutable_let_patterns)]\n                if let TransportConfig::Relay { relay_map, .. } = t {\n                    Some(relay_map.clone())\n                } else {\n                    None\n                }\n            })\n            .next()\n            .unwrap_or_else(RelayMap::empty);\n\n        let ipv6_reported = Arc::new(AtomicBool::new(false));\n\n        let relay_actor_config = RelayActorConfig {\n            my_relay: HomeRelayWatch::default(),","sourceCodeStart":884,"sourceCodeEnd":920,"githubUrl":"https://github.com/n0-computer/iroh/blob/2b4de030ce5e0133f272871a76f0c685c63f552a/iroh/src/socket.rs#L884-L920","documentation":"BindError::InvalidTransportConfig from iroh's socket binding code. During binding, all TransportConfig::Relay entries are collected and more than one is rejected, because the endpoint currently supports at most a single relay transport configuration.","triggerScenarios":"Building an endpoint whose transports contain two or more TransportConfig::Relay entries, then binding. Raised in socket.rs when relay_transport_configs.len() > 1.","commonSituations":"Merging relay configs from multiple sources (config file + code) resulting in duplicate relay transports; appending a custom relay map while a default relay transport was already added; older code patterns that configured several relays before the single-relay restriction.","solutions":["Ensure exactly one TransportConfig::Relay in the transports list before binding.","Merge multiple relay maps into the single Relay transport's relay_map instead of adding multiple relay transports.","Filter out duplicate/default relay transports when constructing the endpoint config programmatically.","If multiple relays are needed, run separate endpoints."],"exampleFix":"// before\nlet transports = vec![\n    TransportConfig::relay_map(relay_map_default),\n    TransportConfig::relay_map(my_relay_map), // second relay -> error\n];\n// after\nlet transports = vec![\n    TransportConfig::relay_map(my_relay_map), // single relay transport\n];","handlingStrategy":"validation","validationCode":"fn validate_relay_transports(transports: &[TransportConfig]) -> Result<(), &'static str> {\n    let n = transports.iter().filter(|t| matches!(t, TransportConfig::Relay { .. })).count();\n    if n > 1 { Err(\"at most one relay transport is supported\") } else { Ok(()) }\n}","typeGuard":"fn is_relay(t: &TransportConfig) -> bool { matches!(t, TransportConfig::Relay { .. }) }","tryCatchPattern":"match Endpoint::bind(...) {\n    Err(e) if e.to_string().contains(\"Invalid transport configuration\") => {\n        // rebuild transports with a single relay entry and retry\n    }\n    other => other,\n}","preventionTips":["Keep exactly one TransportConfig::Relay entry in endpoint config","Merge multiple relay maps into one relay_map instead of multiple relay transports","Sanitize merged configs (file + code) for duplicate relay entries","Validate transports programmatically before binding"],"tags":["network","configuration","relay","transport"],"backgroundTag":"conflicting-config-options","analyzedSha":"2b4de030ce5e0133f272871a76f0c685c63f552a","analyzedAt":"2026-09-08T04:26:47.755Z","contentChangedAt":"2026-09-08T04:26:47.755Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}