hashicorp/nomad · error
failed to validate API versions %v for internal plugin %s: %
Error message
failed to validate API versions %v for internal plugin %s: %v
What it means
selectApiVersion negotiates the highest API version shared between the plugin's PluginApiVersions and the loader's supportedVersions for the plugin type. If it returns an error (no versions listed, invalid versions, or unsupported plugin type), initInternal wraps it with this message and skips the plugin.
Source
Thrown at helper/pluginutils/loader/init.go:142
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
}
if av == "" {
l.logger.Warn("skipping plugin because supported API versions for plugin and Nomad do not overlap", "plugin", k)
continue
}
info.apiVersion = av
// Get the config schema
schema, err := base.ConfigSchema()
if err != nil {
_ = multierror.Append(&mErr, fmt.Errorf("failed to retrieve config schema for internal plugin %s: %v", k, err))
continue
}
info.configSchema = schema
// Store the fingerprinted config
fingerprinted[k] = infoView on GitHub (pinned to 482b49bf1a)
Solutions
- Upgrade Nomad (or the plugin) so the plugin's API versions overlap with the loader's supported versions for its type
- Verify the plugin's PluginInfoResponse.Type is a supported type (e.g. base.PluginTypeCSI) and PluginApiVersions is non-empty with valid versions
- Read the inner %v error to distinguish empty/invalid versions vs unsupported type
Example fix
// before
&base.PluginInfoResponse{Type: "storage", PluginApiVersions: nil}
// after
&base.PluginInfoResponse{Type: base.PluginTypeCSI, PluginApiVersions: []string{"v1"}} Defensive patterns
Strategy: validation
Validate before calling
resp, err := p.PluginInfo()
if err != nil || resp == nil || len(resp.PluginApiVersions) == 0 {
return fmt.Errorf("plugin must declare PluginApiVersions")
}
if _, ok := supportedVersions[resp.Type]; !ok {
return fmt.Errorf("unsupported plugin type %q", resp.Type)
} Type guard
func negotiable(info *base.PluginInfoResponse, supported map[string][]string) bool {
return info != nil && info.Type != "" && len(info.PluginApiVersions) > 0 && supported[info.Type] != nil
} Try / catch
if err := loader.Init(...); err != nil {
if strings.Contains(err.Error(), "failed to validate API versions") {
// compare plugin's PluginApiVersions with Nomad's supported versions
}
} Prevention
- Pin plugin API versions to constants shared between plugin and host
- Upgrade Nomad and plugins together when API versions change
- Log both version lists when negotiation fails to make overlap gaps obvious
When it happens
Trigger: initInternal calls l.selectApiVersion(i) and it errors because: PluginApiVersions is empty, contains unparsable strings, i.Type is not a registered/supported plugin type, or the version lists are malformed.
Common situations: Plugin built against an API the Nomad version doesn't support; plugin reports type "" or a custom type Nomad has no supported versions table for; plugin forgot to declare PluginApiVersions.
Related errors
- PluginInfo info failed for internal plugin %s: %v
- failed to parse version %q for internal plugin %s: %v
- 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/064af34bc962e0f3.
Report an issue: GitHub.