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

  1. Ensure client and server run compatible cloudflared versions (update both).
  2. Confirm the client is actually a cloudflared transport and not other traffic pointed at the tunnel port.
  3. 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

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


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