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
- Set the same remotePort on every proxy in the group — the shared listener serves all members
- Pick the canonical port, apply it to all member configs, and frpc verify each one
- 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
- Fix remotePort once in a shared template variable for the whole group
- Remember group members share one frps listener — different ports means different groups by design
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.