{"record":{"id":"9a3699c0427c12ae","repo":"fatedier/frp","slug":"visitor-s-v","errorCode":null,"errorMessage":"visitor %s: %v","messagePattern":"visitor (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/v1/validation/client.go","lineNumber":216,"sourceCode":"\tvalidator := NewConfigValidator(unsafeFeatures)\n\tvar warnings Warning\n\tif c != nil {\n\t\twarning, err := validator.ValidateClientCommonConfig(c)\n\t\twarnings = AppendError(warnings, warning)\n\t\tif err != nil {\n\t\t\treturn warnings, err\n\t\t}\n\t}\n\n\tfor _, c := range proxyCfgs {\n\t\tif err := ValidateProxyConfigurerForClient(c); err != nil {\n\t\t\treturn warnings, fmt.Errorf(\"proxy %s: %v\", c.GetBaseConfig().Name, err)\n\t\t}\n\t}\n\n\tfor _, c := range visitorCfgs {\n\t\tif err := ValidateVisitorConfigurer(c); err != nil {\n\t\t\treturn warnings, fmt.Errorf(\"visitor %s: %v\", c.GetBaseConfig().Name, err)\n\t\t}\n\t}\n\treturn warnings, nil\n}\n","sourceCodeStart":198,"sourceCodeEnd":221,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/v1/validation/client.go#L198-L221","documentation":"Aggregate wrapper for visitors: ValidateVisitorConfigurer failed for one [[visitors]] entry and the error is prefixed with the visitor's name. The inner %v error carries the actual cause — typically a bad bindPort, missing secretKey for STCP, or an unknown visitor type.","triggerScenarios":"A visitor block (stcp/sudp/xtcp visitors) failing per-type validation: e.g. stcp visitor without serverName, bindPort outside 0..65535, or missing secretKey. Validation stops at the first failing visitor.","commonSituations":"Client-side visitor config drift from server-side proxy config (secretKey mismatch shape); port already implied by another visitor; typos in visitor type field.","solutions":["Parse the inner error text after the visitor name to find the failing field","Correct bindPort/serverName/secretKey per the visitor type's requirements","Run `frpc verify -c frpc.toml` to iterate quickly without starting the client"],"exampleFix":"# before\n[[visitors]]\nname = \"stcp-v\"\ntype = \"stcp\"\nserverName = \"secret-ssh\"\nsecretKey = \"\"\nbindAddr = \"127.0.0.1\"\nbindPort = 6000\n\n# after\n[[visitors]]\nname = \"stcp-v\"\ntype = \"stcp\"\nserverName = \"secret-ssh\"\nsecretKey = \"shared-secret\"\nbindAddr = \"127.0.0.1\"\nbindPort = 6000","handlingStrategy":"try-catch","validationCode":"for _, v := range visitorCfgs {\n    if err := validation.ValidateVisitorConfigurer(v); err != nil {\n        // surface v.GetBaseConfig().Name + err before startup\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := validation.ValidateAllClientConfig(cc, proxies, visitors, uf); err != nil {\n    if after, ok := strings.CutPrefix(err.Error(), \"visitor \"); ok {\n        name, inner, _ := strings.Cut(after, \": \")\n        // handle per-visitor failure keyed by name\n    }\n}","preventionTips":["Keep visitor secretKey/serverName in sync with the server-side proxy definition via a single source of truth","Verify configs with `frpc verify` before rollout"],"tags":["frp","config","visitor","stcp","validation","go"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}