{"record":{"id":"b7f8171448cbaf0e","repo":"cloudflare/cloudflared","slug":"failed-to-format-address-v","errorCode":null,"errorMessage":"Failed to format address: %v","messagePattern":"Failed to format address: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"socks/request.go","lineNumber":127,"sourceCode":"\t\taddrPort = 0\n\n\tcase addr.FQDN != \"\":\n\t\taddrType = fqdnAddress\n\t\taddrBody = append([]byte{byte(len(addr.FQDN))}, addr.FQDN...)\n\t\taddrPort = uint16(addr.Port)\n\n\tcase addr.IP.To4() != nil:\n\t\taddrType = ipv4Address\n\t\taddrBody = []byte(addr.IP.To4())\n\t\taddrPort = uint16(addr.Port)\n\n\tcase addr.IP.To16() != nil:\n\t\taddrType = ipv6Address\n\t\taddrBody = []byte(addr.IP.To16())\n\t\taddrPort = uint16(addr.Port)\n\n\tdefault:\n\t\treturn fmt.Errorf(\"Failed to format address: %v\", addr)\n\t}\n\n\t// Format the message\n\tmsg := make([]byte, 6+len(addrBody))\n\tmsg[0] = socks5Version\n\tmsg[1] = resp\n\tmsg[2] = 0 // Reserved\n\tmsg[3] = addrType\n\tcopy(msg[4:], addrBody)\n\tmsg[4+len(addrBody)] = byte(addrPort >> 8)\n\tmsg[4+len(addrBody)+1] = byte(addrPort & 0xff)\n\n\t// Send the message\n\t_, err := w.Write(msg)\n\treturn err\n}\n\n// readAddrSpec is used to read AddrSpec.","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/socks/request.go#L109-L145","documentation":"sendReply serializes a SOCKS5 reply message with the target address; it supports IPv4, IPv6, and (via a preceding case) FQDN address types. If the net.Addr's IP cannot be encoded as 4 or 16 bytes (To4 and To16 both nil), the address type is unknown and the library returns this error instead of writing a malformed reply.","triggerScenarios":"sendReply being passed an addr whose IP field is neither a valid IPv4 nor IPv6 value — e.g. a zero-value &net.TCPAddr{}, an address with a nil/unparseable IP, or a non-IP net.Addr wrapped to fit.","commonSituations":"Custom dialer or access-policy code constructing a DestAddr/net.TCPAddr with an empty IP string; forwarding addresses produced by non-IP resolvers; a bug in user code that clears req.DestAddr.IP before the handler sends the bind/connect reply.","solutions":["Ensure the addr passed to sendReply/handleConnect has a populated net.IP (parse with net.ParseIP and assign req.DestAddr.IP)","For FQDN destinations without an IP, rely on the FQDN address type rather than passing an invalid IP","Validate constructed addresses with addr.IP != nil and net.ParseIP(addr.String()) before handling the request","If running a custom RequestHandler, check the reply send error and log the offending address"],"exampleFix":"// before\nreq.DestAddr.IP = nil // addr has no IP, reply fails to format\n\n// after\nif ip := net.ParseIP(host); ip != nil {\n    req.DestAddr.IP = ip\n}","handlingStrategy":"validation","validationCode":"if addr == nil || addr.IP == nil || (addr.IP.To4() == nil && addr.IP.To16() == nil) {\n    return fmt.Errorf(\"cannot encode address %v as SOCKS5 reply\", addr)\n}","typeGuard":"func isEncodableAddr(addr net.Addr) bool {\n    ta, ok := addr.(*net.TCPAddr)\n    return ok && ta.IP != nil && (ta.IP.To4() != nil || ta.IP.To16() != nil)\n}","tryCatchPattern":"if err := handleRequest(conn); err != nil && strings.Contains(err.Error(), \"Failed to format address\") {\n    log.Error().Err(err).Msg(\"constructed address lacks a valid IP\")\n}","preventionTips":["Always populate DestAddr.IP via net.ParseIP before invoking the handler","Use FQDN addressing for hostnames instead of empty-IP TCPAddr values","Unit-test any custom address construction with nil-IP cases"],"tags":["network","socks5","address-format"],"backgroundTag":"invalid-argument-value","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}