{"record":{"id":"8123b3e1c9b13c8f","repo":"fatedier/frp","slug":"group-auth-failed","errorCode":null,"errorMessage":"group auth failed","messagePattern":"group auth failed","errorType":"exception","errorClass":"ErrGroupAuthFailed","httpStatus":null,"severity":"error","filePath":"server/group/group.go","lineNumber":22,"sourceCode":"// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage group\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\tErrGroupAuthFailed    = errors.New(\"group auth failed\")\n\tErrGroupParamsInvalid = errors.New(\"group params invalid\")\n\tErrListenerClosed     = errors.New(\"group listener closed\")\n\tErrGroupDifferentPort = errors.New(\"group should have same remote port\")\n\tErrProxyRepeated      = errors.New(\"group proxy repeated\")\n\n\terrGroupStale = errors.New(\"stale group reference\")\n)\n","sourceCodeStart":4,"sourceCodeEnd":30,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/server/group/group.go#L4-L30","documentation":"ErrGroupAuthFailed is returned when a proxy joins an existing load-balance group on frps with a mismatched groupKey. The first proxy to bind a group's listener sets the group key; subsequent members (tcp.go:116, http.go:105, tcpmux.go:124, https.go:97) must present the same groupKey, which acts as a shared secret so unrelated clients cannot join someone else's group.","triggerScenarios":"Two [[proxies]] blocks with the same group name but different groupKey values; rolling out a new groupKey to some clients before others; whitespace/typo differences in groupKey between config files.","commonSituations":"Scaling a group to a second machine and forgetting to copy groupKey; secret rotation done on only part of the fleet; copy-paste between environments (staging key used against prod group).","solutions":["Set identical group and groupKey on every proxy that should join the same load-balance group","After rotating groupKey, update all member clients — mixed keys split the group and late joiners are rejected","Check for stray whitespace or quoting differences in groupKey in TOML/YAML"],"exampleFix":"# client A\n[[proxies]]\nname = \"a\"\ntype = \"tcp\"\ngroup = \"app\"\ngroupKey = \"correct-horse\"\n\n# client B — before: groupKey = \"battery\"  -> ErrGroupAuthFailed\n# after\ngroupKey = \"correct-horse\"","handlingStrategy":"validation","validationCode":"// Before connecting: enforce identical groupKey across members (config management side)\nfor _, p := range proxiesInGroup(\"app\") {\n    if p.GroupKey != expectedKey {\n        return fmt.Errorf(\"proxy %s groupKey mismatch for group app\", p.Name)\n    }\n}","typeGuard":"func isGroupAuthFailed(err error) bool {\n    return errors.Is(err, group.ErrGroupAuthFailed)\n}","tryCatchPattern":"ln, realPort, err := ctl.tcpGroup.Listen(group, groupKey, addr, port)\nif errors.Is(err, group.ErrGroupAuthFailed) {\n    // groupKey differs from the first member — correct the config before retrying\n}","preventionTips":["Distribute groupKey via your secret manager so all members always share the same value","Rotate groupKey atomically: take members offline, change all configs, bring them back"],"tags":["frp","go","group","load-balance","auth","server"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}