fatedier/frp · error · ErrGroupDifferentPort

group should have same remote port

Error message

group should have same remote port

What it means

ErrGroupDifferentPort is returned when a proxy joins an existing TCP group but requests a different remotePort (tcp.go:112). All members of a load-balance group share a single frps listener, so the port (like the address and group key) must match the port the first member registered.

Source

Thrown at server/group/group.go:25

//     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 the same remotePort on every proxy in the group — the shared listener serves all members
  2. Pick the canonical port, apply it to all member configs, and frpc verify each one
  3. If you actually want different ports, they are different groups: use different group names

Example fix

# before — member B has remotePort = 9001 while group uses 9000
# after
[[proxies]]
name = "b"
type = "tcp"
group = "app"
groupKey = "correct-horse"
remotePort = 9000
Defensive patterns

Strategy: validation

Validate before calling

// Config lint: all members of a group must share remotePort
ports := map[string]int{}
for _, p := range proxies {
    if p.Group != "" {
        if prev, ok := ports[p.Group]; ok && prev != p.RemotePort {
            return fmt.Errorf("group %s: remotePort %d != %d", p.Group, p.RemotePort, prev)
        }
        ports[p.Group] = p.RemotePort
    }
}

Type guard

func isGroupDifferentPort(err error) bool {
    return errors.Is(err, group.ErrGroupDifferentPort)
}

Try / catch

if errors.Is(err, group.ErrGroupDifferentPort) {
    // set this member's remotePort to the group's existing port and reconnect
}

Prevention

When it happens

Trigger: Two [[proxies]] with same group/groupKey but remotePort = 9000 on one and 9001 on the other; a member omitting remotePort so it defaults differently; port drift after config refactor.

Common situations: Scaling a service to more frpc instances and hand-editing ports per instance instead of keeping them equal; merging configs where one block was updated to a new port and others were not.

Related errors


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