{"record":{"id":"ec8e7b5777050966","repo":"databendlabs/databend","slug":"invalid-peer-str","errorCode":null,"errorMessage":"invalid peer str: {}","messagePattern":"invalid peer str: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/control/src/import.rs","lineNumber":154,"sourceCode":"    eprintln!(\"Finished import, max_log_id: '{}'\", max_log_id.display());\n\n    Ok(max_log_id)\n}\n\n/// Build `Node` for cluster with new addresses configured.\n///\n/// Raw config is: `<NodeId>=<raft-api-host>:<raft-api-port>[,...]`, e.g. `1=localhost:29103` or `1=localhost:29103,0.0.0.0:19191`\n/// The second part is obsolete grpc api address and will be just ignored. Databend-meta loads Grpc address from config file when starting up.\nfn build_nodes(initial_cluster: Vec<String>, id: u64) -> anyhow::Result<BTreeMap<NodeId, Node>> {\n    eprintln!(\"Initialize Cluster: id={}, {:?}\", id, initial_cluster);\n\n    let mut nodes = BTreeMap::new();\n    for peer in initial_cluster {\n        eprintln!(\"peer:{}\", peer);\n\n        let id_addrs: Vec<&str> = peer.split('=').collect();\n        if id_addrs.len() != 2 {\n            return Err(anyhow::anyhow!(\"invalid peer str: {}\", peer));\n        }\n        let id = u64::from_str(id_addrs[0])?;\n\n        let addrs: Vec<&str> = id_addrs[1].split(',').collect();\n        if addrs.len() > 2 || addrs.is_empty() {\n            return Err(anyhow::anyhow!(\n                \"require 1 or 2 addresses in peer str: {}\",\n                peer\n            ));\n        }\n        let url = Url::parse(&format!(\"http://{}\", addrs[0]))?;\n        let endpoint = match (url.host_str(), url.port()) {\n            (Some(addr), Some(port)) => Endpoint::new(addr, port),\n            _ => {\n                return Err(anyhow::anyhow!(\"invalid peer raft addr: {}\", addrs[0]));\n            }\n        };\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/meta/control/src/import.rs#L136-L172","documentation":"When building initial-cluster nodes for import, build_nodes parses each peer string expected as '<id>=<addr1>[,addr2]'. A peer string that does not split into exactly two '='-separated parts is rejected with 'invalid peer str: {}'.","triggerScenarios":"Passing --initial-cluster entries missing '=' or containing multiple '=' characters, e.g. '1=127.0.0.1' is fine but '1' or 'a=b=c' fails.","commonSituations":"Hand-typing the initial cluster spec; copy-paste errors; shell quoting mangling commas or equals; empty peer entries.","solutions":["Format each peer as '<node-id>=<grpc-addr>[,<grpc-addr2>]', e.g. '1=127.0.0.1:9191'","Check for stray '=' characters or missing address parts and re-quote the argument in the shell","Count entries: the id must be a u64 before the '=' and an address after"],"exampleFix":"// before\n--initial-cluster 1=127.0.0.1 2=127.0.0.1\n// after\n--initial-cluster 1=127.0.0.1:9191 2=127.0.0.1:29191","handlingStrategy":"validation","validationCode":"for peer in initial_cluster {\n    if peer.split('=').count() != 2 {\n        eprintln!(\"invalid peer str: {} (expected <id>=<addr>[,addr2])\", peer);\n    }\n}\n","typeGuard":null,"tryCatchPattern":"match build_nodes(initial_cluster) {\n    Err(e) if e.to_string().starts_with(\"invalid peer str\") => eprintln!(\"fix peer format: id=addr1[,addr2]\"),\n    other => other,\n}","preventionTips":["Quote --initial-cluster arguments in shell to protect '=' and ','","Validate peer strings with a dry-run or echo before invoking metactl","Use consistent id=host:port naming per node"],"tags":["cli","parsing","format"],"backgroundTag":"invalid-argument-format","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}