grpc/grpc-go · error
grpctransport: unknown config name
Error message
grpctransport: unknown config name %q specified in ServerIdentifierExtension
What it means
Returned when ServerIdentifierExtension.ConfigName does not match any key in the configs map passed to NewBuilder (grpc_transport.go:103). The Builder uses ConfigName to look up the credentials bundle, so an unknown name means the credentials cannot be resolved.
Solutions
- Cross-check the ConfigName against the keys passed to grpctransport.NewBuilder.
- If the name comes from bootstrap, ensure the credentials entry exists under "grpc_xds_configs" / the configured configs section.
- Log both the available keys and the requested name at startup to catch drift.
Example fix
// before
b := grpctransport.NewBuilder(map[string]Config{"insecure": {Credentials: creds}})
si.Extensions = grpctransport.ServerIdentifierExtension{ConfigName: "mtls"}
// after
b := grpctransport.NewBuilder(map[string]Config{"mtls": {Credentials: creds}})
si.Extensions = grpctransport.ServerIdentifierExtension{ConfigName: "mtls"} Defensive patterns
Strategy: validation
Validate before calling
func resolveConfig(b *grpctransport.Builder, name string) (grpctransport.Config, error) {
// Builder.configs is private; expose a Contains() helper or track keys at the call site.
// Validation pattern: keep the keys you registered and check membership.
return grpctransport.Config{}, nil
} Try / catch
if err != nil && strings.Contains(err.Error(), "unknown config name") {
// log registered config keys vs requested name, then correct the mismatch
} Prevention
- Define config-name constants and reference them in both NewBuilder and the ServerIdentifierExtension.
- At startup, log every config key you registered.
- Unit-test that each ServerIdentifierExtension.ConfigName resolves.
When it happens
Trigger: builder := grpctransport.NewBuilder(map[string]Config{"insecure": ...}); then Build with a ServerIdentifier whose Extension has ConfigName="mtls" which is not a key in the map.
Common situations: Typo in the config name; config map keys are generated from one source (e.g. bootstrap) and the ServerIdentifier from another and they disagree; refactoring renamed a key but not all references; bootstrap credentials section was pruned.
Related errors
- grpctransport: config
- grpctransport: Extensions field is %T, but must be %T in…
- grpctransport: Extensions is not set in ServerIdentifier
- grpctransport: failed to create connection to server
- grpctransport: ServerURI is not set in ServerIdentifier
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/09916d86f4ede893.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/clients/grpctransport/grpc_transport.go:103
// 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]++
tr := &grpcTransport{cc: cc}
tr.cleanup = b.cleanupFunc(si, tr)
return tr, nil
}
View on GitHub (pinned to 0c51461d27)