{"record":{"id":"eba160c83f750dda","repo":"fatedier/frp","slug":"port-not-allowed","errorCode":null,"errorMessage":"port not allowed","messagePattern":"port not allowed","errorType":"exception","errorClass":"ErrPortNotAllowed","httpStatus":null,"severity":"error","filePath":"server/ports/ports.go","lineNumber":24,"sourceCode":"\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"k8s.io/utils/clock\"\n\n\t\"github.com/fatedier/frp/pkg/config/types\"\n)\n\nconst (\n\tMinPort                    = 1\n\tMaxPort                    = 65535\n\tMaxPortReservedDuration    = time.Duration(24) * time.Hour\n\tCleanReservedPortsInterval = time.Hour\n)\n\nvar (\n\tErrPortAlreadyUsed = errors.New(\"port already used\")\n\tErrPortNotAllowed  = errors.New(\"port not allowed\")\n\tErrPortUnAvailable = errors.New(\"port unavailable\")\n\tErrNoAvailablePort = errors.New(\"no available port\")\n)\n\ntype PortCtx struct {\n\tProxyName  string\n\tPort       int\n\tClosed     bool\n\tUpdateTime time.Time\n}\n\ntype Manager struct {\n\treservedPorts map[string]*PortCtx\n\tusedPorts     map[int]*PortCtx\n\tfreePorts     map[int]struct{}\n\n\tbindAddr string\n\tnetType  string","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/server/ports/ports.go#L6-L42","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Move the proxy's remotePort into the range allowed by frps allowPorts (e.g. start/end or a port-set)","Or ask the frps operator to widen allowPorts to cover the port you need","Alternatively use remotePort = 0 so frps picks from its allowed free pool"],"exampleFix":"# frps.toml — before: allowPorts.start = 6000, allowPorts.end = 6100\n# frpc requests 7000 -> port not allowed\n\n# frps.toml — after\nallowPorts.start = 6000\nallowPorts.end = 8000","handlingStrategy":"validation","validationCode":"// Validate the requested port against the server policy before connecting\nfunc portAllowed(allowPorts *types.PortsRange, port int) bool {\n    if allowPorts == nil {\n        return true\n    }\n    for _, r := range allowPorts.Multiple {\n        if port >= r.Start && port <= r.End { // single port: Start == End\n            return true\n        }\n    }\n    return false\n}","typeGuard":"func isPortNotAllowed(err error) bool {\n    return errors.Is(err, ports.ErrPortNotAllowed)\n}","tryCatchPattern":"if errors.Is(err, ports.ErrPortNotAllowed) {\n    // port is outside frps allowPorts — coordinate with the operator or use remotePort = 0\n}","preventionTips":["Publish the frps allowPorts range to all client teams and encode it in config linting","Never request frps's own bindPort or vhost ports as a remotePort"],"tags":["frp","go","port","policy","server","config"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}