storage: gRPC client does not respect no proxy option
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"
Hmm, maybe I could work around this by passing in an HTTP client with a transport set to not use the proxy.
Ah, I guess not. I get an error if I try to use option.WithHTTPClient(): WithHTTPClient is incompatible with gRPC dial options
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.
AFAIK I am not setting any related config in the environment.
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