hyperium / tonic

A native gRPC client & server implementation with async/await support.
https://docs.rs/tonic
MIT License
10k stars 1.02k forks source link

HTTP/2 was not negotiated connecting to Go-based gRPC service #1427

Closed PeterFaiman closed 8 months ago

PeterFaiman commented 1 year ago

Bug Report

Version

Original issue: 0.8.3 Still reproducible: 0.9.2

Platform

Linux XXX 6.1.0-0.deb11.5-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.12-1~bpo11+1 (2023-03-05) x86_64 GNU/Linux

Description

I was trying to set up opentelemetry-otlp to connect directly to Grafana Cloud, using the tonic connector, but tonic returns an H2NotNegotiated error. As otel uses tonic 0.8.3 at present, I sought to make a minimum reproducible example with the latest tonic (0.9.2).

I don't know for sure if this is a bug in tonic or a bug in grpc-go / Grafana Tempo (https://github.com/grafana/tempo), and I don't know enough about HTTP/2, TLS, or ALPN to figure it out myself. In any case, I would expect any 2 gRPC clients to interoperate cleanly. I am filing the issue here since I have trace logs from the client, but not the server. I am sure the server works / is up, as I can send and view traces forwarded through the Grafana Agent to the same endpoint.

I tried this code:

Example cargo project with tracing: https://github.com/PeterFaiman/tonic-issue-minimal-example

let url = "https://tempo-prod-15-prod-us-west-0.grafana.net:443/v1/traces";
let endpoint = tonic::transport::Endpoint::from_static(url);
endpoint.connect().await?;

I expected to see this happen: connect to the remote server

Instead, this happened: H2NotNegotiated

Full output with TRACE level:

    Finished dev [unoptimized + debuginfo] target(s) in 0.49s
     Running `target/debug/tonic-issue-minimal-example`
2023-07-05T10:51:25.447739Z TRACE tonic::transport::service::reconnect: poll_ready; idle
2023-07-05T10:51:25.458733Z DEBUG rustls::anchors: add_parsable_certificates processed 127 valid and 0 invalid certs
2023-07-05T10:51:25.459138Z TRACE tonic::transport::service::reconnect: poll_ready; connecting
2023-07-05T10:51:25.459385Z TRACE hyper::client::connect::http: Http::connect; scheme=Some("https"), host=Some("tempo-prod-15-prod-us-west-0.grafana.net"), port=Some(Port(443))
2023-07-05T10:51:25.459904Z TRACE tonic::transport::service::reconnect: poll_ready; not ready
2023-07-05T10:51:25.460260Z DEBUG hyper::client::connect::dns: resolving host="tempo-prod-15-prod-us-west-0.grafana.net"
2023-07-05T10:51:25.462710Z TRACE tonic::transport::service::reconnect: poll_ready; connecting
2023-07-05T10:51:25.462930Z DEBUG hyper::client::connect::http: connecting to 35.167.41.0:443
2023-07-05T10:51:25.463332Z TRACE tonic::transport::service::reconnect: poll_ready; not ready
2023-07-05T10:51:25.532619Z TRACE tonic::transport::service::reconnect: poll_ready; connecting
2023-07-05T10:51:25.532944Z DEBUG hyper::client::connect::http: connected to 35.167.41.0:443
2023-07-05T10:51:25.533273Z DEBUG rustls::client::hs: No cached session for DnsName("tempo-prod-15-prod-us-west-0.grafana.net")
2023-07-05T10:51:25.533990Z DEBUG rustls::client::hs: Not resuming any session
2023-07-05T10:51:25.534547Z TRACE rustls::client::hs: Sending ClientHello Message {
    version: TLSv1_0,
    payload: Handshake {
        parsed: HandshakeMessagePayload {
            typ: ClientHello,
            payload: ClientHello(
                ClientHelloPayload {
                    client_version: TLSv1_2,
                    random: d9815be3c7e93ac215dddd5ed22c7bb44f561c05ea665772771cb5ff5711e151,
                    session_id: 5651999649c495283a2b8e83649b79e278625c62010511d0352187c5f2c1fc69,
                    cipher_suites: [
                        TLS13_AES_256_GCM_SHA384,
                        TLS13_AES_128_GCM_SHA256,
                        TLS13_CHACHA20_POLY1305_SHA256,
                        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
                        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
                        TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
                        TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                        TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
                        TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
                    ],
                    compression_methods: [
                        Null,
                    ],
                    extensions: [
                        SupportedVersions(
                            [
                                TLSv1_3,
                                TLSv1_2,
                            ],
                        ),
                        ECPointFormats(
                            [
                                Uncompressed,
                            ],
                        ),
                        NamedGroups(
                            [
                                X25519,
                                secp256r1,
                                secp384r1,
                            ],
                        ),
                        SignatureAlgorithms(
                            [
                                ECDSA_NISTP384_SHA384,
                                ECDSA_NISTP256_SHA256,
                                ED25519,
                                RSA_PSS_SHA512,
                                RSA_PSS_SHA384,
                                RSA_PSS_SHA256,
                                RSA_PKCS1_SHA512,
                                RSA_PKCS1_SHA384,
                                RSA_PKCS1_SHA256,
                            ],
                        ),
                        ExtendedMasterSecretRequest,
                        CertificateStatusRequest(
                            OCSP(
                                OCSPCertificateStatusRequest {
                                    responder_ids: [],
                                    extensions: ,
                                },
                            ),
                        ),
                        ServerName(
                            [
                                ServerName {
                                    typ: HostName,
                                    payload: HostName(
                                        (
                                            74656d706f2d70726f642d31352d70726f642d75732d776573742d302e67726166616e612e6e6574,
                                            DnsName(
                                                "tempo-prod-15-prod-us-west-0.grafana.net",
                                            ),
                                        ),
                                    ),
                                },
                            ],
                        ),
                        SignedCertificateTimestampRequest,
                        KeyShare(
                            [
                                KeyShareEntry {
                                    group: X25519,
                                    payload: 76d431fa83541c90ad7f73a1d247de3fce87ca35349fda27a9c4f61ef337a13f,
                                },
                            ],
                        ),
                        PresharedKeyModes(
                            [
                                PSK_DHE_KE,
                            ],
                        ),
                        Protocols(
                            [
                                ProtocolName(
                                    6832,
                                ),
                            ],
                        ),
                        SessionTicket(
                            Request,
                        ),
                    ],
                },
            ),
        },
        encoded: 0100010f0303d9815be3c7e93ac215dddd5ed22c7bb44f561c05ea665772771cb5ff5711e151205651999649c495283a2b8e83649b79e278625c62010511d0352187c5f2c1fc690014130213011303c02cc02bcca9c030c02fcca800ff010000b2002b00050403040303000b00020100000a00080006001d00170018000d00140012050304030807080608050804060105010401001700000005000501000000000000002d002b00002874656d706f2d70726f642d31352d70726f642d75732d776573742d302e67726166616e612e6e657400120000003300260024001d002076d431fa83541c90ad7f73a1d247de3fce87ca35349fda27a9c4f61ef337a13f002d0002010100100005000302683200230000,
    },
}
2023-07-05T10:51:25.539418Z TRACE tonic::transport::service::reconnect: poll_ready; not ready
2023-07-05T10:51:25.608255Z TRACE tonic::transport::service::reconnect: poll_ready; connecting
2023-07-05T10:51:25.608670Z TRACE rustls::client::hs: We got ServerHello ServerHelloPayload {
    legacy_version: TLSv1_2,
    random: a161d6de0be702adcc1a5d0e2a1e23f5aa319881f2dca29c2670a28d8e6d91bd,
    session_id: 5651999649c495283a2b8e83649b79e278625c62010511d0352187c5f2c1fc69,
    cipher_suite: TLS13_AES_128_GCM_SHA256,
    compression_method: Null,
    extensions: [
        SupportedVersions(
            TLSv1_3,
        ),
        KeyShare(
            KeyShareEntry {
                group: X25519,
                payload: ff5b2394f400c116d7673b15c1d1b82001115fe169dbd18bcd4193adb4bb4b46,
            },
        ),
    ],
}
2023-07-05T10:51:25.610368Z DEBUG rustls::client::hs: Using ciphersuite TLS13_AES_128_GCM_SHA256
2023-07-05T10:51:25.610585Z DEBUG rustls::client::tls13: Not resuming
2023-07-05T10:51:25.610748Z TRACE rustls::client::client_conn: EarlyData rejected
2023-07-05T10:51:25.611840Z TRACE rustls::conn: Dropping CCS
2023-07-05T10:51:25.612066Z DEBUG rustls::client::tls13: TLS1.3 encrypted extensions: [ServerNameAck]
2023-07-05T10:51:25.612204Z DEBUG rustls::client::hs: ALPN protocol is None
2023-07-05T10:51:25.612516Z TRACE tonic::transport::service::reconnect: poll_ready; not ready
2023-07-05T10:51:25.612682Z TRACE tonic::transport::service::reconnect: poll_ready; connecting
2023-07-05T10:51:25.612822Z TRACE rustls::client::tls13: Server cert is [Certificate(b"0\x82\x07l0\x82\x06T\xa0\x03\x02\x01\x02\x02\x10\x08\xbbU\x1d\x8e?\xf9\xd8\xe1\xf4\xed\xc0||\xe3\x8c0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\00O1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x150\x13\x06\x03U\x04\n\x13\x0cDigiCert Inc1)0'\x06\x03U\x04\x03\x13 DigiCert TLS RSA SHA256 2020 CA10\x1e\x17\r230131000000Z\x17\r240302235959Z0a1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x110\x0f\x06\x03U\x04\x08\x13\x08New York1\x110\x0f\x06\x03U\x04\x07\x13\x08New York1\x160\x14\x06\x03U\x04\n\x13\rRaintank Inc.1\x140\x12\x06\x03U\x04\x03\x13\x0bgrafana.com0\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\0\x03\x82\x01\x0f\00\x82\x01\n\x02\x82\x01\x01\0\xa2?\x9b\x9a\x12\xb8\x01K\xef\xf7\xf7J\xe5\xa0\xf1\x06~e\xd3Pk\x90\x04\xc2<\x84x\xde\xe8\xf9\xcf\x11\x82\xc8`h_\xb9\xf9\xa4U\xac\x10\x03\x1b\xaeGR~\xa4e\xba\x81S\x8b\xc7\xff\xbb\xd1\x02p\xcc\x05\xd4\xce\x08K*\x10\xea#\xe1\xecN\xa9\x91\x05\x0b\xa0\x08\x08L\xbam\x88\x03U\xcf,7\xd2\x9ceE\x12\xa66\xacB\xe1\xfc\xc4_\x0c\\\xde\xa1\xe0i`~\xc4\xcc\x02\xfe-\xef\x13\x19\xea\x1e\x80\x14b{\xde\x8dt\xfc[\xf4\xb3\x99\xb9\xbcy~V-6\xde\xafma\r\xf1\x913;eR\xea\xf7Q\xf4={e\x15{\xc7l,\xa3\x0b^9\xae\xea\xe1\xec\x04\x9e\x08\xd6\xd3\x93\xf3Th\x84\xbd>\xfc\xe8\x8f\x8b\xd7-$\xbf\xd3\xa5\xb2\xd1t\xb1B\xa4\x97{h\xb4\xf5\xf3\xa4x{\x9d*O\x02\x10T\x15\xcb\x1b\xddpv\xfa1w\xda\x1a\xc5*}\xc51\xdf\x91\x85\xb4:\xa3\x0cr/Y\xa9F\xc9\xf4V\xa1\xb4(\xc3\x840ZA\xec\xa6\xf7\x02\x03\x01\0\x01\xa3\x82\x0400\x82\x04,0\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14\xb7k\xa2\xea\xa8\xaa\x84\x8cy\xea\xb4\xda\x0f\x98\xb2\xc5\x95v\xb9\xf40\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14AB\xb0\x81\xedJdz\xd34\xc3\x13\xa0\xf4\xc9\xa3m_\x84F0\x81\xdb\x06\x03U\x1d\x11\x04\x81\xd30\x81\xd0\x82\x0bgrafana.com\x82\r*.grafana.com\x82\r*.grafana.net\x82\r*.grafana.org\x82\x1c*.hosted-metrics.grafana.net\x82\r*.raintank.io\x82\x0bgrafana.net\x82\x0bgrafana.org\x82\x0braintank.io\x82\x11*.grafanalabs.com\x82\x0fgrafanalabs.com\x82\x0e*.raintank.com\x82\x0craintank.com0\x0e\x06\x03U\x1d\x0f\x01\x01\xff\x04\x04\x03\x02\x05\xa00\x1d\x06\x03U\x1d%\x04\x160\x14\x06\x08+\x06\x01\x05\x05\x07\x03\x01\x06\x08+\x06\x01\x05\x05\x07\x03\x020\x81\x8f\x06\x03U\x1d\x1f\x04\x81\x870\x81\x840@\xa0>\xa0<\x86:http://crl3.digicert.com/DigiCertTLSRSASHA2562020CA1-4.crl0@\xa0>\xa0<\x86:http://crl4.digicert.com/DigiCertTLSRSASHA2562020CA1-4.crl0>\x06\x03U\x1d \x0470503\x06\x06g\x81\x0c\x01\x02\x020)0'\x06\x08+\x06\x01\x05\x05\x07\x02\x01\x16\x1bhttp://www.digicert.com/CPS0\x7f\x06\x08+\x06\x01\x05\x05\x07\x01\x01\x04s0q0$\x06\x08+\x06\x01\x05\x05\x070\x01\x86\x18http://ocsp.digicert.com0I\x06\x08+\x06\x01\x05\x05\x070\x02\x86=http://cacerts.digicert.com/DigiCertTLSRSASHA2562020CA1-1.crt0\t\x06\x03U\x1d\x13\x04\x020\00\x82\x01}\x06\n+\x06\x01\x04\x01\xd6y\x02\x04\x02\x04\x82\x01m\x04\x82\x01i\x01g\0u\0\xee\xcd\xd0d\xd5\xdb\x1a\xce\xc5\\\xb7\x9d\xb4\xcd\x13\xa22\x87F|\xbc\xec\xde\xc3QHYFq\x1f\xb5\x9b\0\0\x01\x86\x08\x17rU\0\0\x04\x03\0F0D\x02\x1f.x:\xf86\xd5a%$:\xc2@Be\x03bX\xfb\xe2\xc8\x0c~/\xdeArY\xb68\xf9\xbc\x02!\0\xf0\xe9\xe1\xa4\x81\xc7\xd6\xf3\x19\x80\x0c%e\x1d\xac\xcd\x93\x0c%\xc7\xe1\x8c\xbd#6\x87S\x97\rX\x1f\xce\0v\0s\xd9\x9e\x89\x1bL\x96x\xa0 }G\x9d\xe6\xb2\xc6\x1c\xd0Q^q\x19*\x8ck\x80\x10z\xc1wr\xb5\0\0\x01\x86\x08\x17rE\0\0\x04\x03\0G0E\x02!\0\xa6\x8f\xc6V\xaa\xcagv\xdb\xd0\x04W\0\xff4\xa4\"\xc0\xed\xdaNn\xf9\xc3,\x12\xa1 I\nM\x08\x02 \x07j\xdf\xbd#\xf5|2\xb4xi\x8d\x9c\x9f\xb8\xe9\xbaw \x13\xcd\r\xafcs\x14t\x8f\xa4\xf8\x87^\0v\0H\xb0\xe3k\xda\xa6G4\x0f\xe5j\x02\xfa\x9d0\xeb\x1cR\x01\xcbV\xdd,\x81\xd9\xbb\xbf\xab9\xd8\x84s\0\0\x01\x86\x08\x17r\x15\0\0\x04\x03\0G0E\x02 Z\x12A;/\x08\x16\xdeN\xec\xe1\xa8\ngw\xca\xc5m\xc4~i\nH\x8c\xe7\xae;\x9e,\x1a#*\x02!\0\x94\xb2\x16\xc7\x01\xb4Ab\xe3\xf9\x0c;\xbc\x14;\x11\xc4\xf0\xf0g\x86\x8d\x17\xc4\xc3\x9b\xb1\x13\xe82O\xa80\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\0\x03\x82\x01\x01\0B&\xe6\xe2\x90\x9b\xfe\xff\xa8\x9aH<h5|\xa19+\x8e\x99-$\x8b\xeb\x93\x0bn\xa4\xca\x82\x08\x0e\xfd\xb3\xc9g\x85\xb8\x85\xe0\xb1\xd5\xf4\xb8\x16|\xaa\xf3\x7f\x9b\x83U\xbf|L\xee\xcf\xa0X\xf5\x17\xd8\x98\x8a\xe8\xcf\xa3\x08t\x1d3\rL\xee\xfc\xdb[\x7f@\x91g\x80\xfc\xdd;\x12\xfdC>\xad;s\x9e\xe8\x0b\x02\xb4\x97G\x81\x11\xa2b&\xd7\xdeX(\x92\x81\xd6\xf6\xde\x9a$\xb1J.y\n\xc0\xe4\xfb\xd1\\\xd7T\xe6w\x0eSE\xafe\xc18\xb0\xf1\xc3\xba\xf8\xbf\xb3b\x0fo\x82m\xa9\x97z\x13\xfc6)=\xc7\xfc5\xcc\xbe|\x93\x9d\x82\x1c\x1a\xdf\xb1\xc6\xbe\xb5C\xe5Z\x10\xbc?\x8e\0\x1b\xfa\x1a:w\x11\xb0\xc5:\xf3w-\x98X\xdb\xc5\xd6\xfd!\x1e\x95\xe1Sn\xcd\x83cU\xae\x9aM\xeal%&\xb3t*\xdbnu\x8bt\x13\x15\xc0\x07|\x83a\xad\xebq\xed\x91j\xc5q\xf8U\xea\x11L\xdbG\x11\xaf\x88q\x96k\xc4\x8f\x7f\x1cp"), Certificate(b"0\x82\x04\xbe0\x82\x03\xa6\xa0\x03\x02\x01\x02\x02\x10\x06\xd8\xd9\x04\xd5XCF\xf6\x8a/\xa7T\"~\xc40\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\00a1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x150\x13\x06\x03U\x04\n\x13\x0cDigiCert Inc1\x190\x17\x06\x03U\x04\x0b\x13\x10www.digicert.com1 0\x1e\x06\x03U\x04\x03\x13\x17DigiCert Global Root CA0\x1e\x17\r210414000000Z\x17\r310413235959Z0O1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x150\x13\x06\x03U\x04\n\x13\x0cDigiCert Inc1)0'\x06\x03U\x04\x03\x13 DigiCert TLS RSA SHA256 2020 CA10\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\0\x03\x82\x01\x0f\00\x82\x01\n\x02\x82\x01\x01\0\xc1K\xb3eGp\xbc\xddOX\xdb\xec\x9c\xed\xc3f\xe5\x1f1\x13T\xadJfF\x1f,\n\xecd\x07\xe5.\xdc\xdc\xb9\n \xed\xdf\xe3\xc4\xd0\x9e\x9a\xa9z\x1d\x82\x88\xe5\x11V\xdb\x1e\x9fX\xc2Q\xe7,4\r.\xd2\x92\xe1V\xcb\xf1y_\xb3\xbb\x87\xca%\x03{\x9aRAf\x10`OW\x13I\xf0\xe87g\x83\xdf\xe7\xd3KgL\"Q\xa6\xdf\x0e\x99\x10\xedWQt&\xe2}\xc7\xcab.\x13\x1b\x7f#\x88%So\xc14X\0\x8b\x84\xff\xf8\xbe\xa7XI\"{\x96\xad\xa2\x88\x9b\x15\xbc\xa0|\xdf\xe9Q\xa8\xd5\xb0\xed7\xe26\xb4\x82Kb\xb5I\x9a\xec\xc7g\xd6\xe3>\xf5\xe3\xd6\x12^D\xf1\xbfqB}X\x84\x03\x80\xb1\x81\x01\xfa\xf9\xca2\xbb\xb4\x8e'\x87'\xc5+t\xd4\xa8\xd6\x97\xde\xc3d\xf9\xca\xceS\xa2V\xbcx\x17\x8eI\x03)\xae\xfbIO\xa4\x15\xb9\xce\xf2\\\x19Wmky\xa7+\xa2' \x13\xb5\xd0=@\xd3!0\x07\x93\xea\x99\xf5\x02\x03\x01\0\x01\xa3\x82\x01\x820\x82\x01~0\x12\x06\x03U\x1d\x13\x01\x01\xff\x04\x080\x06\x01\x01\xff\x02\x01\00\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xb7k\xa2\xea\xa8\xaa\x84\x8cy\xea\xb4\xda\x0f\x98\xb2\xc5\x95v\xb9\xf40\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14\x03\xdeP5V\xd1L\xbbf\xf0\xa3\xe2\x1b\x1b\xc3\x97\xb2=\xd1U0\x0e\x06\x03U\x1d\x0f\x01\x01\xff\x04\x04\x03\x02\x01\x860\x1d\x06\x03U\x1d%\x04\x160\x14\x06\x08+\x06\x01\x05\x05\x07\x03\x01\x06\x08+\x06\x01\x05\x05\x07\x03\x020v\x06\x08+\x06\x01\x05\x05\x07\x01\x01\x04j0h0$\x06\x08+\x06\x01\x05\x05\x070\x01\x86\x18http://ocsp.digicert.com0@\x06\x08+\x06\x01\x05\x05\x070\x02\x864http://cacerts.digicert.com/DigiCertGlobalRootCA.crt0B\x06\x03U\x1d\x1f\x04;0907\xa05\xa03\x861http://crl3.digicert.com/DigiCertGlobalRootCA.crl0=\x06\x03U\x1d \x046040\x0b\x06\t`\x86H\x01\x86\xfdl\x02\x010\x07\x06\x05g\x81\x0c\x01\x010\x08\x06\x06g\x81\x0c\x01\x02\x010\x08\x06\x06g\x81\x0c\x01\x02\x020\x08\x06\x06g\x81\x0c\x01\x02\x030\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\0\x03\x82\x01\x01\0\x802\xce^\x0b\xddnZ\r\n\xaf\xe1\xd6\x84\xcb\xc0\x8e\xfa\x85p\xed\xda]\xb3\x0c\xf7+u@\xfe\x85\n\xfa\xf31x\xb7pK\x1a\x89X\xba\x80\xbd\xf3k\x1d\xe9~\xcf\x0b\xbaX\x9cY\xd4\x90\xd3\xfdl\xfd\xd0\x98m\xb7q\x82[\xcfm\x0bZ\t\xd0{\xde\xc4C\xd8*\xa4\xde\x9eA&_\xbb\x8f\x99\xcb\xdd\xae\xe1\xa8o\x9f\x87\xfet\xb7\x1f\x1b \xab\xb1O\xc6\xf5g]]\x9b<\xe9\xffi\xf7al\xd6\xd9\xf3\xfd6\xc6\xab\x03\x88v\xd2K.u\x86\xe3\xfc\xd8U}&\xc2\x11w\xdf>\x02\xb6|\xf3\xab{z\x866o\xb8\xf7\xd8\x93q\xcf\x86\xdfs0\xfa{\xab\xed*Y\xc8B\x84;\x11\x17\x1aR\xf3\xc9\x0e\x14}\xa2[rg\xbaq\xedWGf\xc5\xb8\x02Je4^\x8b\xd0*< \x9cQ\x99L\xe7R\x9e\xf7k\x11+\r\x92~\x1d\xe8\x8a\xeb6\x16C\x87\xea*c\xbfu?\xeb\xde\xc4\x03\xbb\n<\xf70\xef\xeb\xafL\xfc\x8b6\x10s>\xf3\xa4")]
2023-07-05T10:51:25.615207Z TRACE tonic::transport::service::reconnect: poll_ready; error
Error: tonic::transport::Error(Transport, hyper::Error(Connect, H2NotNegotiated))

The original code looks like this, in case it matters:

let credentials = http_auth_basic::Credentials::new("ABC", "XYZ");
let mut tonic_metadata = tonic::metadata::MetadataMap::with_capacity(1);
tonic_metadata.insert(
    "authorization",
    credentials.as_http_header().parse().unwrap(),
);

let grafana_cloud_tonic_tracer = opentelemetry_otlp::new_pipeline()
    .tracing()
    .with_exporter(
        opentelemetry_otlp::new_exporter()
            .tonic()
            .with_endpoint("https://tempo-prod-15-prod-us-west-0.grafana.net:443")
            .with_metadata(tonic_metadata),
    )
    .install_batch(opentelemetry::runtime::Tokio)?;

let grafana_cloud_tonic_layer =
    tracing_opentelemetry::layer().with_tracer(grafana_cloud_tonic_tracer);

Registry::default()
    .with(LevelFilter::from(Level::INFO))
    .with(tracing_subscriber::fmt::layer())
    .with(grafana_cloud_tonic_layer)
    .init();
shunkakinoki commented 1 year ago

Getting the same error as well - @PeterFaiman did you happen to find any solutions

LucioFranco commented 1 year ago

You need to use https://docs.rs/tonic/latest/tonic/transport/channel/struct.Endpoint.html#method.tls_config to enable the tls negotiation iirc

abizjak commented 10 months ago

I am experiencing the same issue, even with enabling TLS config explicitly.

onsails commented 8 months ago

Getting the same error when connecting to a service behind Google Cloud Load Balancer. This endpoint can be successfully queried with grpcurl or buf curl --protocol grpc. Also, connecting with tonic to the same service directly (without TLSConfig, directly to a non-tls port of the service which is behind a GCP LB) – works well.

ajwerner commented 8 months ago

The deal seems to be that tonic is enforcing that the server offer ALPN protocol negotiation. This doesn't seem like a standard thing in the gRPC ecosystem. This can commonly arise if you implement a gRPC service that is not using TLS but then you have a load balancer in front of the service that does the TLS termination. While many of these load balancers offer ALPN options (for example, later nginx in the stream plugin), they can be painful to use in more complex scenarios.

The painful code is here https://github.com/hyperium/tonic/blob/23106dd76882a4ffbf2d3ac59c9c403518e429c9/tonic/src/transport/service/tls.rs#L79-L81.

In some cases, this error might help folks who have pointed their client at the wrong server -- instead of getting garbage errors later, they get a hint that the server is not speaking h2. But, as this issue demonstrates, this is not a panacea.

I think that a reasonable but aggressive change would be to change the default behavior to match that of other clients in the ecosystem -- don't require ALPN, and perhaps allow users to opt into the current behavior.

A more measured solution would be to allow users to opt out of the current behavior. One place in which that's a little bit painful is that most users probably end up relying on the default TLS config and don't set the TlsClientConfig (which is pretty painful to use). I put up this approach in https://github.com/hyperium/tonic/pull/1640.