fatedier/frp · error · ErrPortNotAllowed

port not allowed

Error message

port not allowed

What it means

ErrPortNotAllowed is returned by ports.Manager.Acquire when the requested port is neither free nor used within frps — meaning it falls outside the server's allowed port pool. The pool is built from frps's bindPort, vhost ports, and the allowPorts range configured by the operator; anything else is denied by policy.

Source

Thrown at server/ports/ports.go:24

	"strconv"
	"sync"
	"time"

	"k8s.io/utils/clock"

	"github.com/fatedier/frp/pkg/config/types"
)

const (
	MinPort                    = 1
	MaxPort                    = 65535
	MaxPortReservedDuration    = time.Duration(24) * time.Hour
	CleanReservedPortsInterval = time.Hour
)

var (
	ErrPortAlreadyUsed = errors.New("port already used")
	ErrPortNotAllowed  = errors.New("port not allowed")
	ErrPortUnAvailable = errors.New("port unavailable")
	ErrNoAvailablePort = errors.New("no available port")
)

type PortCtx struct {
	ProxyName  string
	Port       int
	Closed     bool
	UpdateTime time.Time
}

type Manager struct {
	reservedPorts map[string]*PortCtx
	usedPorts     map[int]*PortCtx
	freePorts     map[int]struct{}

	bindAddr string
	netType  string

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Move the proxy's remotePort into the range allowed by frps allowPorts (e.g. start/end or a port-set)
  2. Or ask the frps operator to widen allowPorts to cover the port you need
  3. Alternatively use remotePort = 0 so frps picks from its allowed free pool

Example fix

# frps.toml — before: allowPorts.start = 6000, allowPorts.end = 6100
# frpc requests 7000 -> port not allowed

# frps.toml — after
allowPorts.start = 6000
allowPorts.end = 8000
Defensive patterns

Strategy: validation

Validate before calling

// Validate the requested port against the server policy before connecting
func portAllowed(allowPorts *types.PortsRange, port int) bool {
    if allowPorts == nil {
        return true
    }
    for _, r := range allowPorts.Multiple {
        if port >= r.Start && port <= r.End { // single port: Start == End
            return true
        }
    }
    return false
}

Type guard

func isPortNotAllowed(err error) bool {
    return errors.Is(err, ports.ErrPortNotAllowed)
}

Try / catch

if errors.Is(err, ports.ErrPortNotAllowed) {
    // port is outside frps allowPorts — coordinate with the operator or use remotePort = 0
}

Prevention

When it happens

Trigger: Client requests remotePort 7000 while frps allowPorts is configured as only 6000-6100; requesting the frps bindPort or another server-reserved port; allowPorts updated on frps but old client configs still request old ports.

Common situations: Operator restricts allowPorts for security and clients' fixed ports fall outside; new proxy added without coordinating with the frps admin; port requested equals a port frps itself listens on.

Related errors


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