{"record":{"id":"66e1c9873e9557ad","repo":"grpc/grpc-go","slug":"grpc-the-provided-default-service-config-is-inval","errorCode":null,"errorMessage":"grpc: the provided default service config is invalid: %v","messagePattern":"grpc: the provided default service config is invalid: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"clientconn.go","lineNumber":232,"sourceCode":"\tif err := cc.initParsedTargetAndResolverBuilder(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, opt := range globalPerTargetDialOptions {\n\t\topt.DialOptionForTarget(cc.parsedTarget.URL).apply(&cc.dopts)\n\t}\n\n\tchainUnaryClientInterceptors(cc)\n\tchainStreamClientInterceptors(cc)\n\n\tif err := cc.validateTransportCredentials(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif cc.dopts.defaultServiceConfigRawJSON != nil {\n\t\tscpr := parseServiceConfig(*cc.dopts.defaultServiceConfigRawJSON, cc.dopts.maxCallAttempts)\n\t\tif scpr.Err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%s: %v\", invalidDefaultServiceConfigErrPrefix, scpr.Err)\n\t\t}\n\t\tcc.dopts.defaultServiceConfig, _ = scpr.Config.(*ServiceConfig)\n\t}\n\tcc.keepaliveParams = cc.dopts.copts.KeepaliveParams\n\n\tif err = cc.initAuthority(); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Register ClientConn with channelz. Note that this is only done after\n\t// channel creation cannot fail.\n\tcc.channelzRegistration(target)\n\tchannelz.Infof(logger, cc.channelz, \"parsed dial target is: %#v\", cc.parsedTarget)\n\tchannelz.Infof(logger, cc.channelz, \"Channel authority set to %q\", cc.authority)\n\n\tcc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelz)\n\tcc.pickerWrapper = newPickerWrapper()\n","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/clientconn.go#L214-L250","documentation":"WithDefaultServiceConfig(s) stores a raw JSON service config applied as fallback when the resolver provides none (or when WithDisableServiceConfig is set). During NewClient, clientconn.go:229-233 parses it via parseServiceConfig; if parsing fails, NewClient returns nil and this error, because a broken default config would leave the channel unable to pick a balancer.","triggerScenarios":"Calling grpc.NewClient(target, grpc.WithDefaultServiceConfig(badJSON)) where badJSON is invalid JSON, references an unregistered balancer, or has malformed loadBalancingConfig/retryPolicy fields. parseServiceConfig returns a non-nil scpr.Err and clientconn.go:232 wraps it.","commonSituations":"A typo in the service config JSON string; referencing a balancer name that is not registered (e.g., custom balancer not imported); malformed retry policy; quoting errors when building the string programmatically.","solutions":["Run the JSON through a validator and against the gRPC service config schema (https://github.com/grpc/grpc/blob/master/doc/service_config.md).","Ensure any balancer referenced in loadBalancingConfig is registered (import its package side-effect, e.g., _ \"google.golang.org/grpc/balancer/weightedroundrobin\").","Simplify to a known-good config first (e.g., {\"loadBalancingConfig\":[{\"pick_first\":{}}]}) then add fields back incrementally."],"exampleFix":"// before\ncc, err := grpc.NewClient(target, grpc.WithDefaultServiceConfig(\n  `{\"loadBalancingConfig\":[{\"round_robin\"}]}`, // missing colon/braces\n)\n// after\ncc, err := grpc.NewClient(target, grpc.WithDefaultServiceConfig(\n  `{\"loadBalancingConfig\":[{\"round_robin\":{}}]}`,\n))","handlingStrategy":"validation","validationCode":"func validateDefaultServiceConfigJSON(js string) error {\n\tpr := parseServiceConfig(js, 1) // maxAttempts; or use serviceconfig.Parse via the balancer registry\n\treturn pr.Err\n}","typeGuard":null,"tryCatchPattern":"// always check the error from NewClient\ncc, err := grpc.NewClient(target, grpc.WithDefaultServiceConfig(sc))\nif err != nil {\n    return fmt.Errorf(\"invalid default service config: %w\", err)\n}","preventionTips":["Validate the default service config JSON against the gRPC service_config.md schema.","Import any custom balancer packages so their names resolve in loadBalancingConfig.","Start from a minimal known-good config and add fields incrementally with a test."],"tags":["go","grpc","config","service-config","validation","dial"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}