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

  1. 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
  2. Rebuild Nomad with an unmodified plugins/registry so only known-good internal plugins are loaded
  3. 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

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/0d833b1feddd4494. Report an issue: GitHub.