grpc/grpc-go · error

grpc: the credentials require transport level security (use…

Error message

grpc: the credentials require transport level security (use grpc.WithTransportCredentials() to set)

What it means

Thrown by convertCustomConfig when json.Marshal fails to serialize the *structpb.Struct (the value of a TypedStruct) into a json.RawMessage. json.Marshal of a structpb.Struct can fail if the Struct contains invalid proto values that the Struct's JSON encoder cannot represent, such as a null value in an unexpected position or deeply nested structures exceeding encoder limits. This is a rare error because structpb.Struct is designed to be JSON-serializable.

Solutions

  1. Inspect the inner error (%v) from json.Marshal to identify the specific field causing the serialization failure.
  2. Validate the TypedStruct's Struct value before sending: ensure all keys are valid UTF-8 strings and all values are well-formed NullValue, NumberValue, StringValue, BoolValue, Struct, or ListValue.
  3. If the Struct is generated programmatically on the control plane, add a round-trip json.Marshal test before sending the xDS resource.

Example fix

// before: control plane builds a Struct with an invalid value
s := &structpb.Struct{
    Fields: map[string]*structpb.Value{
        "key": {Kind: &structpb.Value_NumberValue{NumberValue: math.NaN()}},
        // NaN is not valid JSON -> marshal error
    },
}

// after: use a valid value
s := &structpb.Struct{
    Fields: map[string]*structpb.Value{
        "key": structpb.NewStringValue("valid"),
    },
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-marshal the TypedStruct value to catch JSON encoding issues:
func validateStructJSON(s *structpb.Struct) error {
    if s == nil {
        return nil
    }
    _, err := json.Marshal(s)
    return err
}

Prevention

When it happens

Trigger: A TypedStruct's value field contains a *structpb.Struct with an internal inconsistency that causes encoding/json marshalling to fail — for instance, a ListValue containing a null Value in a context where the encoder rejects it, or a Struct field whose key contains invalid UTF-8. This is uncommon because proto validation usually catches these at construction time.

Common situations: A control plane that constructs structpb.Struct values programmatically with invalid nested values. A proto deserialization edge case where a malformed Struct passes proto validation but fails JSON marshalling. Extremely large or deeply nested Struct values hitting encoding limits.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/bb7562fb09cdb1d7. Report an issue: GitHub.

Appendix: source

Thrown at clientconn.go:100

	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"},
		OptionalLabels: []string{"grpc.lb.backend_service", "grpc.lb.locality", "grpc.disconnect_error"},
		Default:        false,
	})
	connectionAttemptsSucceededMetric = expstats.RegisterInt64Count(expstats.MetricDescriptor{
		Name:           "grpc.subchannel.connection_attempts_succeeded",
		Description:    "EXPERIMENTAL. Number of successful connection attempts.",
		Unit:           "{attempt}",
		Labels:         []string{"grpc.target"},
		OptionalLabels: []string{"grpc.lb.backend_service", "grpc.lb.locality"},
		Default:        false,

View on GitHub (pinned to 0c51461d27)