{"record":{"id":"80e33bacef230204","repo":"grpc/grpc-go","slug":"grpctransport-extensions-field-is-t-but-must-be","errorCode":null,"errorMessage":"grpctransport: Extensions field is %T, but must be %T in ServerIdentifier","messagePattern":"grpctransport: Extensions field is %T, but must be %T in ServerIdentifier","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/clients/grpctransport/grpc_transport.go","lineNumber":98,"sourceCode":"\t\tconfigs:     configs,\n\t\tconnections: make(map[clients.ServerIdentifier]*grpc.ClientConn),\n\t\trefs:        make(map[clients.ServerIdentifier]int),\n\t}\n}\n\n// Build returns a gRPC-based clients.Transport.\n//\n// The Extension field of the ServerIdentifier must be a ServerIdentifierExtension.\nfunc (b *Builder) Build(si clients.ServerIdentifier) (clients.Transport, error) {\n\tif si.ServerURI == \"\" {\n\t\treturn nil, fmt.Errorf(\"grpctransport: ServerURI is not set in ServerIdentifier\")\n\t}\n\tif si.Extensions == nil {\n\t\treturn nil, fmt.Errorf(\"grpctransport: Extensions is not set in ServerIdentifier\")\n\t}\n\tsce, ok := si.Extensions.(ServerIdentifierExtension)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"grpctransport: Extensions field is %T, but must be %T in ServerIdentifier\", si.Extensions, ServerIdentifierExtension{})\n\t}\n\n\tconfig, ok := b.configs[sce.ConfigName]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"grpctransport: unknown config name %q specified in ServerIdentifierExtension\", sce.ConfigName)\n\t}\n\tif config.Credentials == nil {\n\t\treturn nil, fmt.Errorf(\"grpctransport: config %q has nil credentials bundle\", sce.ConfigName)\n\t}\n\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\n\tif cc, ok := b.connections[si]; ok {\n\t\tif logger.V(2) {\n\t\t\tlogger.Infof(\"Reusing existing connection to the server for ServerIdentifier: %v\", si)\n\t\t}\n\t\tb.refs[si]++","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clients/grpctransport/grpc_transport.go#L80-L116","documentation":"Returned by (*Builder).Build when si.Extensions is populated but is not of type grpctransport.ServerIdentifierExtension (grpc_transport.go:98). The Builder uses a type assertion to read ConfigName, so any other concrete type (including a pointer *ServerIdentifierExtension) is rejected.","triggerScenarios":"Setting si.Extensions to a *ServerIdentifierExtension (pointer) instead of the value type, or to an unrelated struct/int. The type assertion sce, ok := si.Extensions.(ServerIdentifierExtension) fails.","commonSituations":"Caller writes Extensions: &grpctransport.ServerIdentifierExtension{...} (pointer); mixing extensions from a different transport implementation; copy-paste from an example that used a pointer form.","solutions":["Set Extensions to a value (not pointer): grpctransport.ServerIdentifierExtension{ConfigName: name}.","Ensure only one transport package's extension type is in use across the codebase.","The error message prints both the actual and expected types - read them to confirm the fix."],"exampleFix":"// before\nsi.Extensions = &grpctransport.ServerIdentifierExtension{ConfigName: n}\n\n// after\nsi.Extensions = grpctransport.ServerIdentifierExtension{ConfigName: n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isGRPCExtension(si clients.ServerIdentifier) bool {\n    _, ok := si.Extensions.(grpctransport.ServerIdentifierExtension)\n    return ok\n}","tryCatchPattern":"if _, ok := si.Extensions.(grpctransport.ServerIdentifierExtension); !ok {\n    // fix the assignment: use value type, not pointer\n}","preventionTips":["Pass ServerIdentifierExtension by value, not by pointer.","Add a helper that constructs the ServerIdentifier with the correct Extension type.","Write a test that type-asserts Extensions on every identifier your code produces."],"tags":["grpctransport","xds","type-error","configuration"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}