{"record":{"id":"805217f997e882d2","repo":"geektutu/7days-golang","slug":"rpc-client-err-wrong-format-s-expect-protocol-805217","errorCode":null,"errorMessage":"rpc client err: wrong format '%s', expect protocol@addr","messagePattern":"rpc client err: wrong format '(.+?)', expect protocol@addr","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-rpc/day7-registry/client.go","lineNumber":313,"sourceCode":"\t\terr = errors.New(\"unexpected HTTP response: \" + resp.Status)\n\t}\n\treturn nil, err\n}\n\n// DialHTTP connects to an HTTP RPC server at the specified network address\n// listening on the default HTTP RPC path.\nfunc DialHTTP(network, address string, opts ...*Option) (*Client, error) {\n\treturn dialTimeout(NewHTTPClient, network, address, opts...)\n}\n\n// XDial calls different functions to connect to a RPC server\n// according the first parameter rpcAddr.\n// rpcAddr is a general format (protocol@addr) to represent a rpc server\n// eg, http@10.0.0.1:7001, tcp@10.0.0.1:9999, unix@/tmp/geerpc.sock\nfunc XDial(rpcAddr string, opts ...*Option) (*Client, error) {\n\tparts := strings.Split(rpcAddr, \"@\")\n\tif len(parts) != 2 {\n\t\treturn nil, fmt.Errorf(\"rpc client err: wrong format '%s', expect protocol@addr\", rpcAddr)\n\t}\n\tprotocol, addr := parts[0], parts[1]\n\tswitch protocol {\n\tcase \"http\":\n\t\treturn DialHTTP(\"tcp\", addr, opts...)\n\tdefault:\n\t\t// tcp, unix or other transport protocol\n\t\treturn Dial(protocol, addr, opts...)\n\t}\n}\n","sourceCodeStart":295,"sourceCodeEnd":324,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-rpc/day7-registry/client.go#L295-L324","documentation":"Day7-registry XDial rejects any rpcAddr that does not split into exactly two '@'-separated parts, returning this format error. Same contract as earlier days: protocol@addr, e.g. http@10.0.0.1:7001, tcp@10.0.0.1:9999, unix@/tmp/geerpc.sock.","triggerScenarios":"XDial with a missing protocol prefix, an embedded 'user@host' style string, or an address containing multiple '@' characters.","commonSituations":"Passing an HTTP URL like 'http://host:9999' instead of 'http@host:9999'; credentials accidentally included in the address; registry templates producing malformed addresses.","solutions":["Use exactly one '@': protocol on the left, address on the right ('unix@/tmp/geerpc.sock').","Normalize URLs to the protocol@addr form before dialing (strip scheme://).","Use Dial when the protocol is already known and fixed."],"exampleFix":"// before\nXDial(\"http://127.0.0.1:7001\")\n// after\nXDial(\"http@127.0.0.1:7001\")","handlingStrategy":"validation","validationCode":"func toRPCAddr(s string) string {\n    if strings.Contains(s, \"://\") {\n        u, _ := url.Parse(s)\n        return u.Scheme + \"@\" + u.Host\n    }\n    return s\n}\n// then verify: strings.Count(addr, \"@\") == 1","typeGuard":null,"tryCatchPattern":"c, err := geerpc.XDial(toRPCAddr(rawAddr))\nif err != nil {\n    if strings.Contains(err.Error(), \"wrong format\") {\n        return nil, fmt.Errorf(\"expected protocol@addr, got %q\", rawAddr)\n    }\n    return nil, err\n}","preventionTips":["Reject URLs and user@host strings at input boundaries; convert to protocol@addr.","Never embed credentials in rpcAddr strings.","Use unix@/path for local sockets rather than trying to encode paths with '@'.","Document the expected format wherever addresses are configured."],"tags":["rpc","address-format","validation"],"backgroundTag":"invalid-address-format","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}