grpc/grpc-go · error
grpctransport: Extensions field is %T, but must be %T in Ser
Error message
grpctransport: Extensions field is %T, but must be %T in ServerIdentifier
What it means
Builder.Build performs a type assertion si.Extensions.(ServerIdentifierExtension) (grpc_transport.go:96-98). If Extensions is set to any other type (a pointer, a string, a different struct), the assertion fails and this error reports both the actual type and the required type. The extension must be the concrete value type ServerIdentifierExtension, not a pointer.
Source
Thrown at internal/xds/clients/grpctransport/grpc_transport.go:98
configs: configs,
connections: make(map[clients.ServerIdentifier]*grpc.ClientConn),
refs: make(map[clients.ServerIdentifier]int),
}
}
// Build returns a gRPC-based clients.Transport.
//
// The Extension field of the ServerIdentifier must be a ServerIdentifierExtension.
func (b *Builder) Build(si clients.ServerIdentifier) (clients.Transport, error) {
if si.ServerURI == "" {
return nil, fmt.Errorf("grpctransport: ServerURI is not set in ServerIdentifier")
}
if si.Extensions == nil {
return nil, fmt.Errorf("grpctransport: Extensions is not set in ServerIdentifier")
}
sce, ok := si.Extensions.(ServerIdentifierExtension)
if !ok {
return nil, fmt.Errorf("grpctransport: Extensions field is %T, but must be %T in ServerIdentifier", si.Extensions, ServerIdentifierExtension{})
}
config, ok := b.configs[sce.ConfigName]
if !ok {
return nil, fmt.Errorf("grpctransport: unknown config name %q specified in ServerIdentifierExtension", sce.ConfigName)
}
if config.Credentials == nil {
return nil, fmt.Errorf("grpctransport: config %q has nil credentials bundle", sce.ConfigName)
}
b.mu.Lock()
defer b.mu.Unlock()
if cc, ok := b.connections[si]; ok {
if logger.V(2) {
logger.Infof("Reusing existing connection to the server for ServerIdentifier: %v", si)
}
b.refs[si]++View on GitHub (pinned to 03255a9237)
Solutions
- Set Extensions to a ServerIdentifierExtension value (not a pointer): grpctransport.ServerIdentifierExtension{ConfigName: "..."}.
- Ensure no other type is assigned to the Extensions field.
- Double-check that you are using the grpctransport package's extension type, not a similarly named one.
Example fix
// before:
// ext := &grpctransport.ServerIdentifierExtension{ConfigName: "default"}
// si.Extensions = ext // pointer — type assertion fails
// after:
// si.Extensions = grpctransport.ServerIdentifierExtension{ConfigName: "default"} Defensive patterns
Strategy: type-guard
Type guard
// Ensure Extensions is exactly ServerIdentifierExtension (value, not pointer).
func isServerIdentifierExtension(ext any) bool {
_, ok := ext.(grpctransport.ServerIdentifierExtension)
return ok
}
// usage:
// if !isServerIdentifierExtension(si.Extensions) { return errors.New("bad ext type") } Prevention
- Assign the value type grpctransport.ServerIdentifierExtension{}, not a pointer.
- Add a type-assertion guard in your ServerIdentifier factory.
When it happens
Trigger: Extensions is set to *ServerIdentifierExtension (pointer) instead of the value, or to a completely unrelated type. The type assertion in Build rejects it.
Common situations: Passing a pointer to the struct out of habit; using a custom extension type that embeds but is not exactly ServerIdentifierExtension; copy-paste from a different transport builder's extension type.
Related errors
- grpctransport: ServerURI is not set in ServerIdentifier
- grpctransport: Extensions is not set in ServerIdentifier
- grpctransport: unknown config name %q specified in ServerIde
- grpctransport: config %q has nil credentials bundle
- grpctransport: failed to create connection to server %q: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/80e33bacef230204.
Report an issue: GitHub.