cloudflare/cloudflared · error
unknown signature %v
Error message
unknown signature %v
What it means
determineProtocol reads the first 6 bytes (magic signature) from a QUIC stream to identify whether the stream carries the data protocol or the RPC protocol. This error is thrown when the byte sequence read from the stream matches neither known signature, meaning the peer wrote an unrecognized preamble or no preamble at all.
Source
Thrown at tunnelrpc/quic/protocol.go:44
protocolV1 protocolVersion = "01"
protocolVersionLength = 2
)
// determineProtocol reads the first 6 bytes from the stream to determine which protocol is spoken by the client.
// The protocols are magic byte arrays understood by both sides of the stream.
func determineProtocol(stream io.Reader) (protocolSignature, error) {
signature, err := readSignature(stream)
if err != nil {
return protocolSignature{}, err
}
switch signature {
case dataStreamProtocolSignature:
return dataStreamProtocolSignature, nil
case rpcStreamProtocolSignature:
return rpcStreamProtocolSignature, nil
default:
return protocolSignature{}, fmt.Errorf("unknown signature %v", signature)
}
}
func writeDataStreamPreamble(stream io.Writer) error {
if err := writeSignature(stream, dataStreamProtocolSignature); err != nil {
return err
}
return writeVersion(stream)
}
func writeVersion(stream io.Writer) error {
_, err := stream.Write([]byte(protocolV1)[:protocolVersionLength])
return err
}
func readVersion(stream io.Reader) (string, error) {
version := make([]byte, protocolVersionLength)View on GitHub (pinned to 2253eeeb25)
Solutions
- Ensure both ends run compatible cloudflared versions that write the protocol signature before any other data
- Verify the peer writes writeSignature(dataStreamProtocolSignature) or rpcStreamProtocolSignature as the very first 6 bytes on the stream
- Check that no proxy/middleware consumes or rewrites the first bytes of the QUIC stream
- Inspect the %v value in the message to identify what the peer actually sent
Example fix
// before: peer writes payload before the signature
stream.Write([]byte(payload))
// after: write the signature first
if err := writeDataStreamPreamble(stream); err != nil {
return err
}
stream.Write([]byte(payload)) Defensive patterns
Strategy: validation
Validate before calling
// Verify the peer's stream version matches before the handshake
if clientVersion != serverVersion {
return fmt.Errorf("protocol version mismatch: client %s, server %s", clientVersion, serverVersion)
} Try / catch
if _, err := determineProtocol(stream); err != nil {
if strings.Contains(err.Error(), "unknown signature") {
// fall back or close stream and reconnect with a compatible peer
stream.Close()
return errIncompatibleProtocol
}
return err
} Prevention
- Always write the 6-byte protocol signature as the first bytes of any new stream
- Pin compatible cloudflared versions on both ends of the tunnel
- Never interleave custom payload bytes before the signature preamble
When it happens
Trigger: Calling ReadConnectResponseData (or any code path invoking determineProtocol) on a stream whose peer did not write one of the two 6-byte magic signatures (0x0A36CD12A13E for data, 0x52BB825CDB65 for RPC) as the first bytes; version mismatch between client and server writing different preambles; garbage or empty stream data.
Common situations: A cloudflared client of a different version connecting to a server expecting this handshake protocol; a stream opened by a non-cloudflared peer; corrupted or truncated QUIC stream data where the first 6 bytes are not the signature; middleware or proxies that consumed/modified the first bytes.
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
- wrong protocol signature %v
- failed to open a registration control stream: %w
- failed to accept QUIC stream: %w
- unknown protocol %v
- invalid datagram type expected
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/a8db40e7c2c85899.
Report an issue: GitHub.