fatedier/frp · error · ErrGroupAuthFailed

group auth failed

Error message

group auth failed

What it means

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.

Source

Thrown at server/group/group.go:22

// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package group

import (
	"errors"
)

var (
	ErrGroupAuthFailed    = errors.New("group auth failed")
	ErrGroupParamsInvalid = errors.New("group params invalid")
	ErrListenerClosed     = errors.New("group listener closed")
	ErrGroupDifferentPort = errors.New("group should have same remote port")
	ErrProxyRepeated      = errors.New("group proxy repeated")

	errGroupStale = errors.New("stale group reference")
)

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Set identical group and groupKey on every proxy that should join the same load-balance group
  2. After rotating groupKey, update all member clients — mixed keys split the group and late joiners are rejected
  3. Check for stray whitespace or quoting differences in groupKey in TOML/YAML

Example fix

# client A
[[proxies]]
name = "a"
type = "tcp"
group = "app"
groupKey = "correct-horse"

# client B — before: groupKey = "battery"  -> ErrGroupAuthFailed
# after
groupKey = "correct-horse"
Defensive patterns

Strategy: validation

Validate before calling

// Before connecting: enforce identical groupKey across members (config management side)
for _, p := range proxiesInGroup("app") {
    if p.GroupKey != expectedKey {
        return fmt.Errorf("proxy %s groupKey mismatch for group app", p.Name)
    }
}

Type guard

func isGroupAuthFailed(err error) bool {
    return errors.Is(err, group.ErrGroupAuthFailed)
}

Try / catch

ln, realPort, err := ctl.tcpGroup.Listen(group, groupKey, addr, port)
if errors.Is(err, group.ErrGroupAuthFailed) {
    // groupKey differs from the first member — correct the config before retrying
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/8123b3e1c9b13c8f. Report an issue: GitHub.