fatedier/frp · error

invalid max pool count %d, must be non-negative

Error message

invalid max pool count %d, must be non-negative

What it means

NewControl also validates the server-side config: ServerCfg.Transport.MaxPoolCount must be non-negative. This is an operator configuration error on frps, independent of any client input; the control (and thus the client session) is rejected at construction.

Source

Thrown at server/control.go:441

	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,
		workConnCh:    make(chan *proxy.WorkConn, poolCount+workConnPoolCapacityOffset),
		proxies:       make(map[string]proxy.Proxy),
		poolCount:     poolCount,

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Fix frps.toml: set transport.maxPoolCount to a positive value (default 5) or remove it to use the default.
  2. Validate config before deploy: run `frps verify -c frps.toml` or your config linter in CI.
  3. Restart frps after correcting the value.

Example fix

# frps.toml — before
[transport]
maxPoolCount = -1

# after
[transport]
maxPoolCount = 5
Defensive patterns

Strategy: validation

Validate before calling

// startup validation (operator or embedding code)
if cfg.Transport.MaxPoolCount < 0 {
    return fmt.Errorf("transport.maxPoolCount must be >= 0")
}

Prevention

When it happens

Trigger: frps is started with transport.maxPoolCount set to a negative number in its config file. The first client login that constructs a Control hits this check and every subsequent login fails too.

Common situations: Typo or env-var interpolation mistake in frps.toml producing a negative value (e.g. empty var parsed as -1 by a template layer); copying a config snippet with a placeholder; manual edits after an upgrade.

Related errors


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