cloudflare/cloudflared · error
unknown protocol %v
Error message
unknown protocol %v
What it means
The RPC session server (Serve) reads the stream's 6-byte protocol signature and only accepts the RPC stream signature; a data-stream signature yields errDataStreamNotSupported and anything else yields this error. It means the server received a stream preamble it does not recognize as a supported protocol.
Source
Thrown at tunnelrpc/quic/session_server.go:37
func NewSessionManagerServer(sessionManager pogs.SessionManager, responseTimeout time.Duration) *SessionManagerServer {
return &SessionManagerServer{
sessionManager: sessionManager,
responseTimeout: responseTimeout,
}
}
func (s *SessionManagerServer) Serve(ctx context.Context, stream io.ReadWriteCloser) error {
signature, err := determineProtocol(stream)
if err != nil {
return err
}
switch signature {
case rpcStreamProtocolSignature:
break
case dataStreamProtocolSignature:
return errDataStreamNotSupported
default:
return fmt.Errorf("unknown protocol %v", signature)
}
// Every new quic.Stream request aligns to a new RPC request, this is why there is a timeout for the server-side
// of the RPC request.
ctx, cancel := context.WithTimeout(ctx, s.responseTimeout)
defer cancel()
transport := tunnelrpc.SafeTransport(stream)
defer transport.Close()
main := pogs.SessionManager_ServerToClient(s.sessionManager)
rpcConn := tunnelrpc.NewServerConn(transport, main.Client)
defer rpcConn.Close()
select {
case <-rpcConn.Done():
return nil
case <-ctx.Done():View on GitHub (pinned to 2253eeeb25)
Solutions
- Ensure the client writes rpcStreamProtocolSignature as the first 6 bytes when opening an RPC stream
- Align client and server cloudflared versions
- Inspect the %v value in the message to see the actual bytes received
- If the client intended a data stream, use the corresponding data-stream serving path instead
Example fix
// before: client writes data preamble to an RPC-serving stream
writeDataStreamPreamble(stream)
// after: write the RPC signature the server expects
if err := writeSignature(stream, rpcStreamProtocolSignature); err != nil {
return err
} Defensive patterns
Strategy: try-catch
Try / catch
err := server.Serve(ctx, stream)
if err != nil {
if strings.Contains(err.Error(), "unknown protocol") {
// close stream; peer sent an unrecognized preamble
stream.Close()
return errUnsupportedPeerProtocol
}
return err
} Prevention
- Ensure clients write the RPC signature before any data on RPC streams
- Log the received signature bytes to diagnose version skew early
- Upgrade/downgrade peers so both sides speak the same signature scheme
When it happens
Trigger: A peer writes neither rpcStreamProtocolSignature nor dataStreamProtocolSignature as its first 6 bytes before the server calls Serve — e.g. a different cloudflared version, a hand-rolled client, or garbage bytes on the stream.
Common situations: Version skew between client and server where the signature scheme changed; a client sending payload data directly without the preamble; corruption of the first bytes on the stream.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- expect to write %d bytes for RPC stream protocol signature,
- unknown signature %v
- wrong protocol signature %v
- expect to write %d bytes for RPC stream protocol signature,
- invalid datagram type expected
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/9c03483d5b866a12.
Report an issue: GitHub.