fatedier/frp · error
invalid effective pool count %d, cannot safely add %d for wo
Error message
invalid effective pool count %d, cannot safely add %d for work connection pool capacity
What it means
NewControl computes effectivePoolCount = min(client PoolCount, server MaxPoolCount) and checks it against math.MaxInt - workConnPoolCapacityOffset so that poolCount + offset cannot overflow int when sizing the workConnCh channel. An absurdly large value (near MaxInt) fails here instead of panicking on channel creation.
Source
Thrown at server/control.go:449
ctx context.Context
doneCh chan struct{}
serverMetrics metrics.ServerMetrics
}
func NewControl(ctx context.Context, sessionCtx *SessionContext) (*Control, error) {
if sessionCtx.LoginMsg.PoolCount < 0 {
return nil, fmt.Errorf("invalid pool count %d, must be non-negative", sessionCtx.LoginMsg.PoolCount)
}
if sessionCtx.ServerCfg.Transport.MaxPoolCount < 0 {
return nil, fmt.Errorf(
"invalid max pool count %d, must be non-negative",
sessionCtx.ServerCfg.Transport.MaxPoolCount,
)
}
effectivePoolCount := min(int64(sessionCtx.LoginMsg.PoolCount), sessionCtx.ServerCfg.Transport.MaxPoolCount)
maxPoolCountForChannel := int64(math.MaxInt) - int64(workConnPoolCapacityOffset)
if effectivePoolCount > maxPoolCountForChannel {
return nil, fmt.Errorf(
"invalid effective pool count %d, cannot safely add %d for work connection pool capacity",
effectivePoolCount, workConnPoolCapacityOffset,
)
}
poolCount := int(effectivePoolCount)
ctl := &Control{
sessionCtx: sessionCtx,
workConnCh: make(chan *proxy.WorkConn, poolCount+workConnPoolCapacityOffset),
proxies: make(map[string]proxy.Proxy),
poolCount: poolCount,
portsUsedNum: 0,
runID: sessionCtx.LoginMsg.RunID,
state: controlStateCreated,
xl: xlog.FromContextSafe(ctx),
ctx: ctx,
doneCh: make(chan struct{}),
serverMetrics: metrics.Server,
}View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Cap pool counts to realistic values in config (single digits to low hundreds).
- If you run a public frps, validate/limit login fields at the trust boundary before control creation.
- Reject the client session — this value cannot be honoured, so retrying with the same number is futile.
Example fix
# frps.toml — hard ceiling for any client [transport] maxPoolCount = 100
Defensive patterns
Strategy: validation
Validate before calling
const sanePoolMax = 1024
if loginMsg.PoolCount > sanePoolMax || cfg.Transport.MaxPoolCount > sanePoolMax {
return fmt.Errorf("pool count unrealistically large")
} Prevention
- Clamp pool counts at a trust boundary when running public frps.
- Never feed unvalidated ints from the wire into resource sizing.
When it happens
Trigger: A client (or misconfigured server max) supplies a pool count within a few units of 2^63-1 on 64-bit. make(chan ..., huge) would try to allocate an impossible buffer, so the guard rejects it first.
Common situations: Malicious or fuzzed login frames with extreme integers; config values accidentally set to huge numbers (e.g. pasting a bit pattern); custom clients reusing an uninitialised int that happens to be large.
Related errors
- exec configuration is required when type is 'exec'
- file path cannot be empty
- exec command cannot be empty
- exec env name cannot be empty
- exec env name cannot contain '='
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/e36216ea74a2c9b3.
Report an issue: GitHub.