hashicorp/packer · error

invalid self-reported version %q: %s

Error message

invalid self-reported version %q: %s

What it means

checkVersion parsed the version string reported by the plugin's `describe` output and it isn't valid semver. Returned as a ContinuableInstallError so InstallLatest skips to the next candidate version. The plugin binary is present but reports a malformed version.

Source

Thrown at packer/plugin-getter/plugins.go:989

	desc := pluginsdk.SetDescription{}
	err = json.Unmarshal(out, &desc)

	return desc, err
}

// checkVersion checks the described version of a plugin binary against the requested version constriant.
// A ContinuableInstallError is returned upon a version mismatch to indicate that the caller should try the next
// available version. A PrereleaseInstallError is returned to indicate an unsupported version install.
func checkVersion(binPath string, identifier string, version *goversion.Version) error {
	desc, err := GetPluginDescription(binPath)
	if err != nil {
		err := fmt.Errorf("failed to describe plugin binary %q: %s", binPath, err)
		return &ContinuableInstallError{Err: err}
	}
	descVersion, err := goversion.NewSemver(desc.Version)
	if err != nil {
		err := fmt.Errorf("invalid self-reported version %q: %s", desc.Version, err)
		return &ContinuableInstallError{Err: err}
	}
	if descVersion.Core().Compare(version.Core()) != 0 {
		err := fmt.Errorf("binary reported version (%q) is different from the expected %q, skipping", desc.Version, version.String())
		return &ContinuableInstallError{Err: err}
	}
	if version.Prerelease() != "" {
		return &PrereleaseInstallError{
			PluginSrc: identifier,
			Err:       errors.New("binary reported a pre-release version of " + version.String()),
		}
	}
	// Since only final releases can be installed remotely, a non-empty prerelease version
	// means something's not right on the release, as it should report a final version.
	//
	// Therefore to avoid surprises (and avoid being able to install a version that
	// cannot be loaded), we error here, and advise users to manually install the plugin if they
	// need it.

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Rebuild the plugin setting a valid semver in its version (check how the release pipeline injects it)
  2. Use an official release of the plugin instead of a locally built/dev binary
  3. Skip the local copy: remove it from the plugins dir and let packer download a released version
  4. If it's your plugin, set pluginsdk.SetDescription Version to a valid semver string (e.g. "1.0.0")

Example fix

// before (plugin main.go built without version)
Version: os.Getenv("VERSION"), // empty at runtime
// after
go build -ldflags "-X main.version=1.2.3" .
Defensive patterns

Strategy: validation

Validate before calling

// validate the version string before feeding it to semver parsing
import "regexp"
var semverRe = regexp.MustCompile(`^v?\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$`)
if !semverRe.MatchString(desc.Version) {
    return fmt.Errorf("plugin reports non-semver version %q", desc.Version)
}

Prevention

When it happens

Trigger: goversion.NewSemver(desc.Version) fails — the plugin's SetDescription/Version field contains a non-semver string (e.g. "v1beta", "dev", empty, or free-form text) instead of a valid semver like 1.2.3.

Common situations: Custom/in-house plugins built without setting a proper sdk version; plugins built from a git checkout without version ldflags; third-party plugins not following the plugin SDK versioning conventions.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/7b963634609480d4. Report an issue: GitHub.