{"record":{"id":"0d833b1feddd4494","repo":"hashicorp/nomad","slug":"plugininfo-info-failed-for-internal-plugin-s-v","errorCode":null,"errorMessage":"PluginInfo info failed for internal plugin %s: %v","messagePattern":"PluginInfo info failed for internal plugin (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/pluginutils/loader/init.go","lineNumber":126,"sourceCode":"\t\tif !ok {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"internal plugin %s doesn't meet base plugin interface\", k))\n\t\t\tcontinue\n\t\t}\n\n\t\tinfo := &pluginInfo{\n\t\t\tfactory: config.Factory,\n\t\t\tconfig:  config.Config,\n\t\t}\n\n\t\t// Try to retrieve a user specified config\n\t\tif userConfig, ok := configs[k.Name]; ok && userConfig.Config != nil {\n\t\t\tinfo.config = userConfig.Config\n\t\t}\n\n\t\t// Fingerprint base info\n\t\ti, err := base.PluginInfo()\n\t\tif err != nil {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"PluginInfo info failed for internal plugin %s: %v\", k, err))\n\t\t\tcontinue\n\t\t}\n\t\tinfo.baseInfo = i\n\n\t\t// Parse and set the plugin version\n\t\tv, err := version.NewVersion(i.PluginVersion)\n\t\tif err != nil {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"failed to parse version %q for internal plugin %s: %v\", i.PluginVersion, k, err))\n\t\t\tcontinue\n\t\t}\n\t\tinfo.version = v\n\n\t\t// Detect the plugin API version to use\n\t\tav, err := l.selectApiVersion(i)\n\t\tif err != nil {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"failed to validate API versions %v for internal plugin %s: %v\", i.PluginApiVersions, k, err))\n\t\t\tcontinue\n\t\t}","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/pluginutils/loader/init.go#L108-L144","documentation":"During initInternal, the loader fingerprints each built-in (internal) plugin by calling base.PluginInfo() to get its PluginInfoResponse. If that call fails, the error is appended to a multierror and the plugin is skipped. It indicates the internal plugin's base plugin implementation returned an error while describing itself.","triggerScenarios":"Calling NewPluginLoader (via init) when one of the registered internal plugin factories returns a base implementation whose PluginInfo() errors, e.g. a misconfigured plugin base or factory returning a partial implementation.","commonSituations":"A newly added internal plugin returns an error from PluginInfo (often because its config or state is invalid at startup); a factory constructs a plugin whose PluginInfo depends on unreadable runtime state; a plugin registered under a type with a broken base struct.","solutions":["Check the wrapped %v error from PluginInfo() in the logs to find the plugin named by %s and fix the root cause in that plugin's implementation","Rebuild Nomad with an unmodified plugins/registry so only known-good internal plugins are loaded","If you develop a custom internal plugin, ensure PluginInfo returns a valid PluginInfoResponse with PluginVersion and PluginApiVersions populated"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before constructing the loader, fingerprint each internal plugin yourself\nfor k, factory := range internalPlugins {\n    base, err := factory()\n    if err != nil { t.Fatalf(\"plugin %s factory: %v\", k, err) }\n    if _, err := base.PluginInfo(); err != nil { t.Fatalf(\"plugin %s PluginInfo: %v\", k, err) }\n}","typeGuard":"func pluginInfoOK(b base.BasePlugin) (*base.PluginInfoResponse, bool) {\n    i, err := b.PluginInfo()\n    return i, err == nil && i != nil\n}","tryCatchPattern":"// Go: inspect the aggregated multierror\nif err := loader.Init(...); err != nil {\n    if merr, ok := err.(*multierror.Error); ok {\n        for _, e := range merr.Errors {\n            if strings.Contains(e.Error(), \"PluginInfo info failed\") { log.Warn(\"skipping broken plugin\", \"err\", e) }\n        }\n    }\n}","preventionTips":["Keep internal plugins in the vetted registry; fingerprint them in CI unit tests","Ensure PluginInfo is pure metadata and cannot depend on failing runtime state","Always check the wrapped inner error for the real cause"],"tags":["go","plugin-loader","nomad","fingerprinting"],"backgroundTag":"plugin-info-fingerprint-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}