cloudflare/cloudflared · error
unknown protocol %v
Error message
unknown protocol %v
What it means
CloudflaredServer.Serve reads the 6-byte protocol signature from an incoming QUIC stream and dispatches on it. If the signature matches neither the data-stream nor RPC-stream signature, the server returns this error because it cannot identify the protocol.
Source
Thrown at tunnelrpc/quic/cloudflared_server.go:48
configManager: configManager,
responseTimeout: responseTimeout,
}
}
// Serve executes the defined handlers in ServerStream on the provided stream if it is a proper RPC stream with the
// correct preamble protocol signature.
func (s *CloudflaredServer) Serve(ctx context.Context, stream io.ReadWriteCloser) error {
signature, err := determineProtocol(stream)
if err != nil {
return err
}
switch signature {
case dataStreamProtocolSignature:
return s.handleRequest(ctx, &RequestServerStream{stream})
case rpcStreamProtocolSignature:
return s.handleRPC(ctx, stream)
default:
return fmt.Errorf("unknown protocol %v", signature)
}
}
func (s *CloudflaredServer) handleRPC(ctx context.Context, stream io.ReadWriteCloser) error {
ctx, cancel := context.WithTimeout(ctx, s.responseTimeout)
defer cancel()
transport := tunnelrpc.SafeTransport(stream)
defer transport.Close()
main := pogs.CloudflaredServer_ServerToClient(s.sessionManager, s.configManager)
rpcConn := tunnelrpc.NewServerConn(transport, main.Client)
defer rpcConn.Close()
// We ignore the errors here because if cloudflared fails to handle a request, we will just move on.
select {
case <-rpcConn.Done():
case <-ctx.Done():
}View on GitHub (pinned to 2253eeeb25)
Solutions
- Ensure client and server run compatible cloudflared versions (update both).
- Confirm the client is actually a cloudflared transport and not other traffic pointed at the tunnel port.
- Re-establish the connection; a garbled first packet is transient.
Defensive patterns
Strategy: validation
Validate before calling
var sig protocolSignature
if _, err := io.ReadFull(r, sig[:]); err != nil { return err }
if sig != dataStreamProtocolSignature && sig != rpcStreamProtocolSignature {
return fmt.Errorf("unknown protocol %v", sig)
} Type guard
func knownSignature(s protocolSignature) bool {
return s == dataStreamProtocolSignature || s == rpcStreamProtocolSignature
} Prevention
- Pin matching cloudflared versions on both ends of a tunnel
- Only point cloudflared-capable clients at the muxer port
- Log the raw signature bytes on dispatch failure to diagnose skew
When it happens
Trigger: A client opens a QUIC stream to CloudflaredServer and writes a first payload whose signature bytes match neither dataStreamProtocolSignature (0x0A36CD12A13E) nor rpcStreamProtocolSignature (0x52BB825CDB65).
Common situations: See trigger scenarios.
Related errors
- invalid datagram type expected
- unsupported error type: %s
- ErrDatagramHeaderTooSmall
- ErrDatagramResponseMsgTooLargeMaximum
- Unsupported SOCKS version: %v
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/5a6d7e55e5766e3a.
Report an issue: GitHub.