cloudflare/cloudflared · error
flow not found
Error message
flow not found
What it means
ErrSessionNotFound (message 'flow not found') indicates that no session has been registered for the given request ID in the SessionManager. GetSession looks up its internal session map and returns this sentinel when the key is absent. It is the normal signal that a payload datagram arrived for an unknown or expired flow.
Source
Thrown at quic/v3/manager.go:17
package v3
import (
"errors"
"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 sessionView on GitHub (pinned to 2253eeeb25)
Solutions
- Register the session via RegisterSession and wait for the registration response before sending payload datagrams
- Handle errors.Is(err, v3.ErrSessionNotFound) by dropping the packet and sending an ICMP port-unreachable-style response or a registration challenge to the client
- Check for session idle timeout/expiry configuration that is too aggressive for your traffic pattern
- Verify the RequestID used for lookup matches the one used at registration
Example fix
// before
session, err := manager.GetSession(datagram.RequestID())
if err != nil {
return err // aborts handling on unknown flows
}
// after
session, err := manager.GetSession(datagram.RequestID())
if errors.Is(err, v3.ErrSessionNotFound) {
// respond with registration-required response and drop packet
conn.SendRegistrationRequired(datagram.RequestID())
return nil
} else if err != nil {
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// no pre-check available; existence is only knowable via GetSession // optionally track registered RequestIDs locally before lookup
Try / catch
session, err := manager.GetSession(requestID)
if errors.Is(err, v3.ErrSessionNotFound) {
// unknown/expired flow: prompt re-registration or drop packet
return
} else if err != nil {
return err
} Prevention
- Complete registration before sending payload datagrams
- Tune idle timeouts to outlast typical flow gaps
- Handle post-teardown packets by answering with a registration-required response
- Log unknown RequestIDs to spot client ID mismatches
When it happens
Trigger: Calling manager.GetSession(requestID) for an ID that was never registered, was already unregistered, or whose session timed out.
Common situations: UDP packets arriving after session teardown/expiry before the client re-registers; mismatched RequestIDs between client and server; sending payload datagrams before the registration response is processed.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- invalid datagram type expected
- flow is in use by another connection
- flow is already registered for this connection
- flow registration rate limited
- flow was closed directly
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/6dfb2f1e6352120e.
Report an issue: GitHub.