fatedier/frp · error
invalid pool count %d, must be non-negative
Error message
invalid pool count %d, must be non-negative
What it means
NewControl validates the login message from frpc: LoginMsg.PoolCount must be non-negative. A negative pool count is a malformed request, so control creation is refused before any resources are allocated.
Source
Thrown at server/control.go:438
lifecycleMu sync.Mutex
state controlState
activated bool
handoffBarrier <-chan struct{}
interruptOnce sync.Once
interruptErr error
mu sync.RWMutex
xl *xlog.Logger
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,View on GitHub (pinned to 6c8a8d0a97)
Solutions
- If you write a custom client, always send a zero-or-positive PoolCount (0 means create work conns on demand).
- Inspect the raw login frame (enable trace logging on frps) to find who sends a negative value.
- Upgrade mismatched frpc builds to a released version.
Example fix
// custom client — before loginMsg.PoolCount = -1 // after loginMsg.PoolCount = 0
Defensive patterns
Strategy: validation
Validate before calling
// custom client before login
if loginMsg.PoolCount < 0 { loginMsg.PoolCount = 0 } Try / catch
if _, err := server.NewControl(ctx, sessionCtx); err != nil {
return err // malformed login: reject session, do not retry unchanged
} Prevention
- Always default-construct login messages; Go zero values satisfy the invariant.
- Fuzz-test your client's serialisation of numeric fields.
When it happens
Trigger: A client sends a Login message with PoolCount < 0 — only possible from a hand-rolled or corrupted client, since stock frpc always sends >= 0. Also reachable from unit tests or custom clients built against the msg package.
Common situations: Custom clients/replays with wrong field types; integer underflow in generated login messages; fuzzing the login endpoint; protocol deserialization bugs in third-party clients.
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/f19f7fa6e4422742.
Report an issue: GitHub.