{"record":{"id":"e1e112f9724604fe","repo":"hashicorp/nomad","slug":"failed-to-parse-plugin-q-v-version-q-v","errorCode":null,"errorMessage":"failed to parse plugin %q (%v) version %q: %v","messagePattern":"failed to parse plugin %q \\((.+?)\\) version %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/pluginutils/loader/init.go","lineNumber":382,"sourceCode":"\traw, err := rpcClient.Dispense(base.PluginTypeBase)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Cast the plugin to the base type\n\tbplugin := raw.(base.BasePlugin)\n\n\t// Retrieve base plugin information\n\ti, err := bplugin.PluginInfo()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get plugin info for plugin %q: %v\", info.exePath, err)\n\t}\n\tinfo.baseInfo = i\n\n\t// Parse and set the plugin version\n\tv, err := version.NewVersion(i.PluginVersion)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse plugin %q (%v) version %q: %v\",\n\t\t\ti.Name, info.exePath, i.PluginVersion, err)\n\t}\n\tinfo.version = v\n\n\t// Detect the plugin API version to use\n\tav, err := l.selectApiVersion(i)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to validate API versions %v for plugin %s (%v): %v\", i.PluginApiVersions, i.Name, info.exePath, err)\n\t}\n\tif av == \"\" {\n\t\tl.logger.Warn(\"skipping plugin because supported API versions for plugin and Nomad do not overlap\", \"plugin\", i.Name, \"path\", info.exePath)\n\t\treturn nil, nil\n\t}\n\tinfo.apiVersion = av\n\n\t// Retrieve the schema\n\tschema, err := bplugin.ConfigSchema()\n\tif err != nil {","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/pluginutils/loader/init.go#L364-L400","documentation":"After PluginInfo() succeeds, fingerprintPlugin() parses i.PluginVersion with hashicorp/go-version's version.NewVersion. This error is returned when the version string reported by the plugin is not a valid semver-compatible version. The plugin is skipped and cannot be registered because its version cannot be compared against constraints.","triggerScenarios":"version.NewVersion(i.PluginVersion) fails because the plugin's PluginInfoResponse.PluginVersion is empty, or contains a non-semantic string like \"dev\", \"v1\", \"1.0.0-beta+\" (malformed), or free-form text.","commonSituations":"Hand-written plugins that set PluginVersion to something like \"latest\" or leave it empty; plugins using non-semver internal versioning schemes; typos such as \"0.1.0.1\" (four segments).","solutions":["Make the plugin return a valid semver string in PluginInfoResponse.PluginVersion (e.g. \"0.1.0\").","Remove leading issues: 'v' prefix is allowed, but no extra dots/dashes; validate with a semver checker.","Rebuild and redeploy the plugin with the corrected version string.","If you cannot patch the plugin, remove it from plugin_dir to stop the error.","Confirm with the plugin vendor that the released binary reports a semver PluginVersion."],"exampleFix":"// before\nreturn &base.PluginInfoResponse{..., PluginVersion: \"dev\"}, nil\n// after\nreturn &base.PluginInfoResponse{..., PluginVersion: \"0.1.0\"}, nil","handlingStrategy":"validation","validationCode":"// validate the plugin's reported version is semver before deploying\nimport \"github.com/hashicorp/go-version\"\n_, err := version.NewVersion(pluginInfo.PluginVersion)\nif err != nil {\n\tlog.Fatalf(\"plugin version %q is not semver: %v\", pluginInfo.PluginVersion, err)\n}","typeGuard":null,"tryCatchPattern":"// Go: detect and isolate the bad plugin\nif _, err := loader.Load(); err != nil {\n\tif strings.Contains(err.Error(), \"failed to parse plugin\") {\n\t\tlog.Printf(\"skipping plugin with invalid version string: %v\", err)\n\t}\n}","preventionTips":["Always set PluginVersion to a valid semver string (e.g. \"1.2.0\"); never \"dev\" or empty.","Add a CI check that asserts the plugin's PluginInfoResponse version parses via go-version.","Use a shared version constant in the plugin source to avoid typos.","Pin hashicorp/go-version in the plugin to a version consistent with Nomad's."],"tags":["plugin-loader","nomad","semver","fingerprinting"],"backgroundTag":"invalid-version-string","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"}