cloudflare/cloudflared · error

flow registration rate limited

Error message

flow registration rate limited

What it means

ErrSessionRegistrationRateLimited is returned when a session registration is rejected because the flow limiter has no capacity left: manager.RegisterSession calls s.limiter.Acquire(management.UDP) and maps any limiter rejection to this sentinel. It protects the server from resource exhaustion by capping the number of concurrent UDP flows.

Solutions

  1. Raise the UDP flow limit configuration if the workload legitimately needs more concurrent flows
  2. Ensure sessions are unregistered on close/timeout so capacity is returned to the limiter
  3. Add client-side backoff and retry on errors.Is(err, v3.ErrSessionRegistrationRateLimited)
  4. Audit for leaked sessions (register-without-unregister) that slowly exhaust the limiter

Example fix

// before
_, err := manager.RegisterSession(&request, eyeball) // rejects under load
// after
_, err := manager.RegisterSession(&request, eyeball)
if errors.Is(err, v3.ErrSessionRegistrationRateLimited) {
    time.Sleep(backoff) // exponential backoff before retry
    return retry(ctx)
}
Defensive patterns

Strategy: retry

Validate before calling

// check flow usage before registration if the limiter exposes a count
// e.g. if limiter.Active(management.UDP) >= maxFlows { wait }

Try / catch

_, err := manager.RegisterSession(&request, eyeball)
if errors.Is(err, v3.ErrSessionRegistrationRateLimited) {
    select {
    case <-time.After(backoff):
        return retryRegister(ctx)
    case <-ctx.Done():
        return ctx.Err()
    }
}

Prevention

When it happens

Trigger: Calling RegisterSession (directly or via handleSessionRegistrationDatagram) when the UDP flow limiter is already at its configured maximum of active flows.

Common situations: Traffic spikes or flow leaks where sessions are registered but never unregistered, hitting the cap; overly low flow-limit configuration for the workload; a client opening thousands of UDP flows (or an abuse/flood pattern).

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/b868f66175d1cc3a. Report an issue: GitHub.

Appendix: source

Thrown at quic/v3/manager.go:23

	"sync"

	"github.com/rs/zerolog"

	"github.com/cloudflare/cloudflared/ingress"
	"github.com/cloudflare/cloudflared/management"

	cfdflow "github.com/cloudflare/cloudflared/flow"
)

var (
	// ErrSessionNotFound indicates that a session has not been registered yet for the request id.
	ErrSessionNotFound = errors.New("flow not found")
	// ErrSessionBoundToOtherConn is returned when a registration already exists for a different connection.
	ErrSessionBoundToOtherConn = errors.New("flow is in use by another connection")
	// ErrSessionAlreadyRegistered is returned when a registration already exists for this connection.
	ErrSessionAlreadyRegistered = errors.New("flow is already registered for this connection")
	// ErrSessionRegistrationRateLimited is returned when a registration fails due to rate limiting on the number of active flows.
	ErrSessionRegistrationRateLimited = errors.New("flow registration rate limited")
)

type SessionManager interface {
	// RegisterSession will register a new session if it does not already exist for the request ID.
	// During new session creation, the session will also bind the UDP socket for the origin.
	// If the session exists for a different connection, it will return [ErrSessionBoundToOtherConn].
	RegisterSession(request *UDPSessionRegistrationDatagram, conn DatagramConn) (Session, error)
	// GetSession returns an active session if available for the provided connection.
	// If the session does not exist, it will return [ErrSessionNotFound]. If the session exists for a different
	// connection, it will return [ErrSessionBoundToOtherConn].
	GetSession(requestID RequestID) (Session, error)
	// UnregisterSession will remove a session from the current session manager. It will attempt to close the session
	// before removal.
	UnregisterSession(requestID RequestID)
}

type sessionManager struct {
	sessions     map[RequestID]Session

View on GitHub (pinned to 2253eeeb25)