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.

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)

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.