hashicorp/nomad · error
PluginInfo info failed for internal plugin %s: %v
Error message
PluginInfo info failed for internal plugin %s: %v
What it means
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.
Source
Thrown at helper/pluginutils/loader/init.go:126
if !ok {
_ = multierror.Append(&mErr, fmt.Errorf("internal plugin %s doesn't meet base plugin interface", k))
continue
}
info := &pluginInfo{
factory: config.Factory,
config: config.Config,
}
// Try to retrieve a user specified config
if userConfig, ok := configs[k.Name]; ok && userConfig.Config != nil {
info.config = userConfig.Config
}
// Fingerprint base info
i, err := base.PluginInfo()
if err != nil {
_ = multierror.Append(&mErr, fmt.Errorf("PluginInfo info failed for internal plugin %s: %v", k, err))
continue
}
info.baseInfo = i
// Parse and set the plugin version
v, err := version.NewVersion(i.PluginVersion)
if err != nil {
_ = multierror.Append(&mErr, fmt.Errorf("failed to parse version %q for internal plugin %s: %v", i.PluginVersion, k, err))
continue
}
info.version = v
// Detect the plugin API version to use
av, err := l.selectApiVersion(i)
if err != nil {
_ = multierror.Append(&mErr, fmt.Errorf("failed to validate API versions %v for internal plugin %s: %v", i.PluginApiVersions, k, err))
continue
}View on GitHub (pinned to 482b49bf1a)
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
Defensive patterns
Strategy: validation
Validate before calling
// before constructing the loader, fingerprint each internal plugin yourself
for k, factory := range internalPlugins {
base, err := factory()
if err != nil { t.Fatalf("plugin %s factory: %v", k, err) }
if _, err := base.PluginInfo(); err != nil { t.Fatalf("plugin %s PluginInfo: %v", k, err) }
} Type guard
func pluginInfoOK(b base.BasePlugin) (*base.PluginInfoResponse, bool) {
i, err := b.PluginInfo()
return i, err == nil && i != nil
} Try / catch
// Go: inspect the aggregated multierror
if err := loader.Init(...); err != nil {
if merr, ok := err.(*multierror.Error); ok {
for _, e := range merr.Errors {
if strings.Contains(e.Error(), "PluginInfo info failed") { log.Warn("skipping broken plugin", "err", e) }
}
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to parse version %q for internal plugin %s: %v
- failed to validate API versions %v for internal plugin %s: %
- failed to retrieve config schema for internal plugin %s: %v
- nil plugin info given
- plugin provided no compatible API versions
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0d833b1feddd4494.
Report an issue: GitHub.