{"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/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/clients/grpctransport/grpc_transport.go#L80-L116","documentation":"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.","triggerScenarios":"Extensions is set to *ServerIdentifierExtension (pointer) instead of the value, or to a completely unrelated type. The type assertion in Build rejects it.","commonSituations":"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.","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."],"exampleFix":"// before:\n//   ext := &grpctransport.ServerIdentifierExtension{ConfigName: \"default\"}\n//   si.Extensions = ext // pointer — type assertion fails\n// after:\n//   si.Extensions = grpctransport.ServerIdentifierExtension{ConfigName: \"default\"}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Ensure Extensions is exactly ServerIdentifierExtension (value, not pointer).\nfunc isServerIdentifierExtension(ext any) bool {\n    _, ok := ext.(grpctransport.ServerIdentifierExtension)\n    return ok\n}\n// usage:\n//   if !isServerIdentifierExtension(si.Extensions) { return errors.New(\"bad ext type\") }","tryCatchPattern":null,"preventionTips":["Assign the value type grpctransport.ServerIdentifierExtension{}, not a pointer.","Add a type-assertion guard in your ServerIdentifier factory."],"tags":["xds","grpctransport","type-mismatch","grpc"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}