google-cloud-go icon indicating copy to clipboard operation
google-cloud-go copied to clipboard

storage: gRPC client does not respect no proxy option

Open horgh opened this issue 7 months ago • 5 comments

Client

Storage

Environment

Ubuntu noble x86 on GCP

go version go1.24.4 linux/amd64

Code and Dependencies

package main

import (
        "context"
        "errors"
        "flag"
        "log"
        "os"

        "cloud.google.com/go/storage"
        "google.golang.org/api/option"
        "google.golang.org/grpc"
)

func main() {
        bucket := flag.String("bucket", "", "Bucket to use")

        flag.Parse()

        if *bucket == "" {
                flag.Usage()
                os.Exit(1)
        }

        ctx := context.Background()

        client, err := storage.NewGRPCClient(
                ctx,
                option.WithGRPCDialOption(grpc.WithNoProxy()),
        )
        if err != nil {
                log.Fatal(err)
        }

        _, err = client.Bucket(*bucket).Attrs(ctx)
        if err != nil {
                if errors.Is(err, storage.ErrBucketNotExist) {
                        log.Println("bucket does not exist")
                        return
                }
                log.Fatal(err)
        }

        log.Println("bucket exists")
}

go.mod
module github.com/horgh/gcs-grpc-test

go 1.24.4

require (
        cloud.google.com/go/storage v1.55.0
        google.golang.org/api v0.236.0
        google.golang.org/grpc v1.73.0
)

require (
        cel.dev/expr v0.23.0 // indirect
        cloud.google.com/go v0.121.1 // indirect
        cloud.google.com/go/auth v0.16.1 // indirect
        cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
        cloud.google.com/go/compute/metadata v0.7.0 // indirect
        cloud.google.com/go/iam v1.5.2 // indirect
        cloud.google.com/go/monitoring v1.24.2 // indirect
        github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect
        github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect
        github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect
        github.com/cespare/xxhash/v2 v2.3.0 // indirect
        github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect
        github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
        github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
        github.com/felixge/httpsnoop v1.0.4 // indirect
        github.com/go-jose/go-jose/v4 v4.0.5 // indirect
        github.com/go-logr/logr v1.4.2 // indirect
        github.com/go-logr/stdr v1.2.2 // indirect
        github.com/google/s2a-go v0.1.9 // indirect
        github.com/google/uuid v1.6.0 // indirect
        github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
        github.com/googleapis/gax-go/v2 v2.14.2 // indirect
        github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
        github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
        github.com/zeebo/errs v1.4.0 // indirect
        go.opentelemetry.io/auto/sdk v1.1.0 // indirect
        go.opentelemetry.io/contrib/detectors/gcp v1.36.0 // indirect
        go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
        go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
        go.opentelemetry.io/otel v1.36.0 // indirect
        go.opentelemetry.io/otel/metric v1.36.0 // indirect
        go.opentelemetry.io/otel/sdk v1.36.0 // indirect
        go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect
        go.opentelemetry.io/otel/trace v1.36.0 // indirect
        golang.org/x/crypto v0.38.0 // indirect
        golang.org/x/net v0.40.0 // indirect
        golang.org/x/oauth2 v0.30.0 // indirect
        golang.org/x/sync v0.14.0 // indirect
        golang.org/x/sys v0.33.0 // indirect
        golang.org/x/text v0.25.0 // indirect
        golang.org/x/time v0.11.0 // indirect
        google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
        google.golang.org/genproto/googleapis/api v0.0.0-20250512202823-5a2f75b736a9 // indirect
        google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
        google.golang.org/protobuf v1.36.6 // indirect
)

Expected behavior

No proxy is used and GCS can be used

Actual behavior

Proxy set in the https_proxy environment variable is used. I see connection attempts to monitoring.googleapis.com and directpath-pa.googleapis.com. Since my proxy doesn't allow connections to these, my program hangs trying to connect to them.

Additional context

I've been using cloud.google.com/go/storage for some time and noticed there was gRPC support, so I wanted to switch to that.

My environment has an HTTP proxy set via environment variables, e.g. export https_proxy=http://127.0.0.1:8888.

For GCP APIs I don't want to use the proxy, so I disable using it via option.WithGRPCDialOption(grpc.WithNoProxy()). This doesn't seem to work for the GCS gRPC client right now.

If I leave it running for a while, I eventually see connection errors:

$ (cd go/foo/ && go run . -bucket foo)
2025/06/09 22:07:31 rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp 127.0.0.1:8888: connect: connection refused"

horgh avatar Jun 09 '25 22:06 horgh

Hmm, maybe I could work around this by passing in an HTTP client with a transport set to not use the proxy.

horgh avatar Jun 09 '25 22:06 horgh

Ah, I guess not. I get an error if I try to use option.WithHTTPClient(): WithHTTPClient is incompatible with gRPC dial options

horgh avatar Jun 09 '25 22:06 horgh

I'm attempting to temporarily work around this by passing no_proxy environment variables. That appears to work, although I would rather not have to globally set this for my programs.

However I see this printed by my programs after enabling gRPC:

2025/06/26 22:10:44 ERROR: [xds] Attempt to set a bootstrap configuration even though one is already set via environment variables.

It seems to only happen when using the gRPC client.

horgh avatar Jun 27 '25 15:06 horgh

AFAIK I am not setting any related config in the environment.

horgh avatar Jun 27 '25 15:06 horgh

Hi @horgh, sorry for the delay in getting back to you here. We will investigate why the NoProxy() option is not working. Re: xds error, this warning can be safely ignored. It was resolved so if you pick up grpc 1.74.2 or later you will no longer see it. See: https://github.com/googleapis/google-cloud-go/issues/12430

BrennaEpp avatar Oct 16 '25 00:10 BrennaEpp