grpc/grpc-go · error
grpc: no transport security set (use grpc.WithTransportCrede
Error message
grpc: no transport security set (use grpc.WithTransportCredentials(insecure.NewCredentials()) explicitly or set credentials)
What it means
errNoTransportSecurity (clientconn.go:87-90) is returned by validateTransportCredentials (clientconn.go:480-483) when NewClient/Dial is called with neither TransportCredentials nor a CredsBundle. gRPC requires you to make an explicit security choice: real TLS credentials OR an explicit insecure credential.
Source
Thrown at clientconn.go:90
errConnDrain = errors.New("grpc: the connection is drained")
// errConnClosing indicates that the connection is closing.
errConnClosing = errors.New("grpc: the connection is closing")
// errConnIdling indicates the connection is being closed as the channel
// is moving to an idle mode due to inactivity.
errConnIdling = errors.New("grpc: the connection is closing due to channel idleness")
// invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default
// service config.
invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid"
// PickFirstBalancerName is the name of the pick_first balancer.
PickFirstBalancerName = pickfirst.Name
)
// The following errors are returned from Dial and DialContext
var (
// errNoTransportSecurity indicates that there is no transport security
// being set for ClientConn. Users should either set one or explicitly
// call WithInsecure DialOption to disable security.
errNoTransportSecurity = errors.New("grpc: no transport security set (use grpc.WithTransportCredentials(insecure.NewCredentials()) explicitly or set credentials)")
// errTransportCredsAndBundle indicates that creds bundle is used together
// with other individual Transport Credentials.
errTransportCredsAndBundle = errors.New("grpc: credentials.Bundle may not be used with individual TransportCredentials")
// errNoTransportCredsInBundle indicated that the configured creds bundle
// returned a transport credentials which was nil.
errNoTransportCredsInBundle = errors.New("grpc: credentials.Bundle must return non-nil transport credentials")
// errTransportCredentialsMissing indicates that users want to transmit
// security information (e.g., OAuth2 token) which requires secure
// connection on an insecure connection.
errTransportCredentialsMissing = errors.New("grpc: the credentials require transport level security (use grpc.WithTransportCredentials() to set)")
)
var (
disconnectionsMetric = expstats.RegisterInt64Count(expstats.MetricDescriptor{
Name: "grpc.subchannel.disconnections",
Description: "EXPERIMENTAL. Number of times the selected subchannel becomes disconnected.",
Unit: "{disconnection}",
Labels: []string{"grpc.target"},View on GitHub (pinned to 03255a9237)
Solutions
- For plaintext/local dev: pass grpc.WithTransportCredentials(insecure.NewCredentials()) (import google.golang.org/grpc/credentials/insecure).
- For production: pass grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)) with a proper *tls.Config.
- If you need per-RPC auth too, combine WithTransportCredentials + WithPerRPCCredentials (never rely on implicit insecure).
- Double-check no DialOption is shadowing/overwriting the credentials slice.
Example fix
// before — no credentials at all
cc, err := grpc.NewClient("passthrough:///localhost:8080")
// err: grpc: no transport security set ...
// after — explicit insecure for local dev
import "google.golang.org/grpc/credentials/insecure"
cc, err := grpc.NewClient("passthrough:///localhost:8080",
grpc.WithTransportCredentials(insecure.NewCredentials())) Defensive patterns
Strategy: validation
Validate before calling
// Validate creds are set BEFORE constructing the ClientConn
func mustCreds(c credentials.TransportCredentials) credentials.TransportCredentials {
if c == nil {
return insecure.NewCredentials() // explicit, never implicit
}
return c
}
cc, err := grpc.NewClient(target, grpc.WithTransportCredentials(mustCreds(tlsOrNone)))
if err != nil { /* errNoTransportSecurity caught here, at construction */ } Try / catch
// NewClient returns this synchronously; handle the constructor error
cc, err := grpc.NewClient(target, opts...)
if err != nil {
if strings.Contains(err.Error(), "no transport security set") {
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
cc, err = grpc.NewClient(target, opts...)
}
} Prevention
- Always pass an explicit WithTransportCredentials (TLS or insecure.NewCredentials()).
- Never assume a default; there is intentionally no implicit insecure.
- Lint Dial/DialContext/NewClient calls for missing credentials.
When it happens
Trigger: grpc.NewClient/Dial/DialContext is invoked with no WithTransportCredentials(...) and no WithCredentialsBundle(...). The check runs during channel init and fails synchronously from the constructor.
Common situations: Migrating from the removed grpc.WithInsecure()/grpc.WithBlock() APIs without adding insecure.NewCredentials(); forgetting the credentials DialOption; new sample code copied without the security line; localhost dev dial without TLS.
Related errors
- grpc: credentials.Bundle may not be used with individual Tra
- grpc: credentials.Bundle must return non-nil transport crede
- grpc: the credentials require transport level security (use
- AuthInfo is nil
- ALTS: untrusted platform. ALTS is only supported on GCP
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/489a327eafe6ad54.
Report an issue: GitHub.