{"record":{"id":"c5703e5b7e883cb0","repo":"cloudflare/cloudflared","slug":"wrong-protocol-signature-v","errorCode":null,"errorMessage":"wrong protocol signature %v","messagePattern":"wrong protocol signature (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tunnelrpc/quic/request_client_stream.go","lineNumber":43,"sourceCode":"\tmsg, err := connectRequest.ToPogs()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := writeDataStreamPreamble(rcs); err != nil {\n\t\treturn err\n\t}\n\treturn capnp.NewEncoder(rcs).Encode(msg)\n}\n\n// ReadConnectResponseData reads the response from the rpc stream to a ConnectResponse.\nfunc (rcs *RequestClientStream) ReadConnectResponseData() (*pogs.ConnectResponse, error) {\n\tsignature, err := determineProtocol(rcs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif signature != dataStreamProtocolSignature {\n\t\treturn nil, fmt.Errorf(\"wrong protocol signature %v\", signature)\n\t}\n\n\t// This is a NO-OP for now. We could cause a branching if we wanted to use multiple versions.\n\tif _, err := readVersion(rcs); err != nil {\n\t\treturn nil, err\n\t}\n\n\tmsg, err := capnp.NewDecoder(rcs).Decode()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tr := &pogs.ConnectResponse{}\n\tif err := r.FromPogs(msg); err != nil {\n\t\treturn nil, err\n\t}\n\treturn r, nil\n}","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/tunnelrpc/quic/request_client_stream.go#L25-L61","documentation":"ReadConnectResponseData first sniffs the stream's 6-byte protocol signature via determineProtocol, then requires it to be the data-stream signature. If the stream turns out to be an RPC stream (or anything else), this error is returned: the caller expected a data stream but got a different stream type.","triggerScenarios":"Calling ReadConnectResponseData on a stream whose peer wrote rpcStreamProtocolSignature (0x52BB825CDB65) as its preamble instead of dataStreamProtocolSignature (0x0A36CD12A13E) — e.g. the client opened an RPC-style stream but the server expected a connect/data stream.","commonSituations":"Client and server disagree on stream type for the same QUIC stream; mixing session_client (RPC) and request_client_stream (data) semantics across cloudflared versions; wiring a stream to the wrong reader.","solutions":["Make the client write the data-stream signature (writeDataStreamPreamble) before sending connect data","Verify the stream is being opened as a data/connect stream, not an RPC stream","Align client and server cloudflared versions so both agree on stream typing","Log/compare the %v signature value to confirm which stream type the peer sent"],"exampleFix":"// before: client opens stream with RPC preamble\nNewSessionClient(ctx, stream, timeout)\n// after: open as data stream\nif err := writeDataStreamPreamble(stream); err != nil {\n    return err\n}\n// then server-side ReadConnectResponseData succeeds","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := rcs.ReadConnectResponseData()\nif err != nil {\n    if strings.Contains(err.Error(), \"wrong protocol signature\") {\n        // the stream is not a data stream; route to RPC handling or reject\n        return errWrongStreamType\n    }\n    return err\n}","preventionTips":["Open data streams with writeDataStreamPreamble and RPC streams with the RPC signature — never mix","Verify which stream type the client opened before calling ReadConnectResponseData","Keep client/server cloudflared versions aligned"],"tags":["quic","protocol-handshake","stream"],"backgroundTag":"invalid-argument-value","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}