{"record":{"id":"0160a3ab7dfb4ffb","repo":"fatedier/frp","slug":"bind-port-is-required","errorCode":null,"errorMessage":"bind port is required","messagePattern":"bind port is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/v1/validation/visitor.go","lineNumber":52,"sourceCode":"\tcase *v1.XTCPVisitorConfig:\n\t\treturn validateXTCPVisitorConfig(v)\n\tdefault:\n\t\treturn errors.New(\"unknown visitor config type\")\n\t}\n\treturn nil\n}\n\nfunc validateVisitorBaseConfig(c *v1.VisitorBaseConfig) error {\n\tif c.Name == \"\" {\n\t\treturn errors.New(\"name is required\")\n\t}\n\n\tif c.ServerName == \"\" {\n\t\treturn errors.New(\"server name is required\")\n\t}\n\n\tif c.BindPort == 0 {\n\t\treturn errors.New(\"bind port is required\")\n\t}\n\treturn nil\n}\n\nfunc validateXTCPVisitorConfig(c *v1.XTCPVisitorConfig) error {\n\tif !slices.Contains([]string{\"kcp\", \"quic\"}, c.Protocol) {\n\t\treturn fmt.Errorf(\"protocol should be kcp or quic\")\n\t}\n\treturn nil\n}\n","sourceCodeStart":34,"sourceCodeEnd":63,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/v1/validation/visitor.go#L34-L63","documentation":"Validation error from validateVisitorBaseConfig: a visitor entry has bindPort set to 0 (the Go zero value for an unset port). The visitor listens locally on bindAddr:bindPort to expose the remote service, so an explicit non-zero local port is mandatory. Third check in visitor base validation.","triggerScenarios":"A [[visitors]] entry with bindPort omitted or set to 0. Note 0 is treated as 'missing', so a genuine desire to use port 0 (random port) is rejected — frp requires a concrete port.","commonSituations":"Copying a proxy block (which uses remotePort) and forgetting visitors need bindPort; assuming frpc picks a free port automatically; TOML key typo BindPort/bindport; programmatic configs leaving VisitorBaseConfig.BindPort unset.","solutions":["Add bindPort = 9000 (a free local TCP port) to the visitor entry.","Also set bindAddr = \"127.0.0.1\" if you want the visitor loopback-only (bindAddr itself is optional with a default).","Check the port is not already in use on the machine running frpc."],"exampleFix":"# before\n[[visitors]]\nname = \"v\"\ntype = \"stcp\"\nserverName = \"stcp-srv\"\nsecretKey = \"s\"\nbindAddr = \"127.0.0.1\"\n\n# after\n[[visitors]]\nname = \"v\"\ntype = \"stcp\"\nserverName = \"stcp-srv\"\nsecretKey = \"s\"\nbindAddr = \"127.0.0.1\"\nbindPort = 9000","handlingStrategy":"validation","validationCode":"base := v.GetBaseConfig()\nif base == nil || base.BindPort == 0 {\n    return errors.New(\"visitor requires an explicit non-zero bindPort\")\n}","typeGuard":"func visitorBindPortSet(c v1.VisitorConfigurer) bool {\n    base := c.GetBaseConfig()\n    return c != nil && base != nil && base.BindPort != 0\n}","tryCatchPattern":"if err := validation.ValidateVisitorConfigurer(v); err != nil {\n    if strings.Contains(err.Error(), \"bind port is required\") {\n        // choose a free local port and set bindPort\n    }\n    return err\n}","preventionTips":["Visitors need a concrete local port; port 0 / random is not supported.","Template visitors with name/type/serverName/secretKey/bindAddr/bindPort.","Check for port collisions with other local listeners."],"tags":["config","visitor","validation","frpc","port"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}