{"record":{"id":"d32e6c6abf1d4748","repo":"grpc/grpc-go","slug":"no-certificate-provider-builder-found-for-q","errorCode":null,"errorMessage":"no certificate provider builder found for %q","messagePattern":"no certificate provider builder found for %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/tls/certprovider/store.go","lineNumber":183,"sourceCode":"\t\tstoreKey: sk,\n\t\tstore:    provStore,\n\t}\n\tprovStore.providers[sk] = wp\n\treturn newSingleCloseWrappedProvider(wp), nil\n}\n\n// String returns the provider name and config as a colon separated string.\nfunc (bc *BuildableConfig) String() string {\n\treturn fmt.Sprintf(\"%s:%s\", bc.name, string(bc.config))\n}\n\n// ParseConfig is a convenience function to create a BuildableConfig given a\n// provider name and configuration. Returns an error if there is no registered\n// builder for the given name or if the config parsing fails.\nfunc ParseConfig(name string, config any) (*BuildableConfig, error) {\n\tparser := getBuilder(name)\n\tif parser == nil {\n\t\treturn nil, fmt.Errorf(\"no certificate provider builder found for %q\", name)\n\t}\n\treturn parser.ParseConfig(config)\n}\n\n// GetProvider is a convenience function to create a provider given the name,\n// config and build options.\nfunc GetProvider(name string, config any, opts BuildOptions) (Provider, error) {\n\tbc, err := ParseConfig(name, config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn bc.Build(opts)\n}\n","sourceCodeStart":165,"sourceCodeEnd":197,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/tls/certprovider/store.go#L165-L197","documentation":"certprovider.ParseConfig(name, config) looked up a builder for `name` in the global registry and found none. Builders self-register via certprovider.Register in their init() (e.g. the pemfile plugin registers \"file_watcher\"), so an unknown name means the plugin package was never imported or the name is misspelled.","triggerScenarios":"Calling ParseConfig(\"file_watcher\", ...) without an `import _ \"google.golang.org/grpc/credentials/tls/certprovider/pemfile\"` somewhere in the binary; passing a typo like \"filesystem_watcher\" or \"file-watch\"; using a provider name from a different gRPC language.","commonSituations":"Forgetting the blank import of the provider package; renaming a provider name across versions; conditional imports behind build tags that excluded the provider in the active build.","solutions":["Add the blank import for the provider package, e.g. `import _ \"google.golang.org/grpc/credentials/tls/certprovider/pemfile\"`.","Verify the exact registered name (pemfile registers PluginName = \"file_watcher\").","If you wrote a custom provider, ensure certprovider.Register(&yourBuilder{}) runs in an init() of an imported package."],"exampleFix":"// before\nimport (\n    \"google.golang.org/grpc/credentials/tls/certprovider\"\n)\ncertprovider.ParseConfig(\"file_watcher\", raw)\n\n// after\nimport (\n    \"google.golang.org/grpc/credentials/tls/certprovider\"\n    _ \"google.golang.org/grpc/credentials/tls/certprovider/pemfile\"\n)\ncertprovider.ParseConfig(\"file_watcher\", raw)","handlingStrategy":"validation","validationCode":"func isProviderRegistered(name string) bool {\n    // no public lookup; rely on a build-time check by attempting a no-op ParseConfig\n    _, err := certprovider.ParseConfig(name, json.RawMessage(`{}`))\n    return err == nil || !strings.Contains(err.Error(), \"no certificate provider builder\")\n}","typeGuard":null,"tryCatchPattern":"bc, err := certprovider.ParseConfig(name, raw)\nif err != nil {\n    if strings.Contains(err.Error(), \"no certificate provider builder\") {\n        return fmt.Errorf(\"forgot to import provider %q? %w\", name, err)\n    }\n    return err\n}","preventionTips":["Add a blank import of the provider package (e.g. _ .../pemfile) wherever you ParseConfig.","Centralize provider registration in an init package imported by main.","Document the registered PluginName for each provider you use."],"tags":["grpc","certprovider","plugin-registration","init","config"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}