pulumi/pulumi · error

module does not have semver compatible version

Error message

module does not have semver compatible version

What it means

normalizeVersion must produce a semver version for a provider dependency so it can be reported to the engine. When semver.ParseTolerant cannot parse the module's version string, this error is thrown. It happens when a module's resolved version is not a real semantic version (e.g. a module with no tagged release resolved to a bare revision, or a hand-edited go.mod with a bogus version).

Source

Thrown at sdk/go/pulumi-language-go/main.go:648

	}

	for _, path := range paths {
		plugin, err := plugin.LoadPulumiPluginJSON(path)
		if err != nil {
			if os.IsNotExist(err) {
				continue
			}
			return nil, err
		}
		return plugin, nil
	}
	return nil, nil
}

func normalizeVersion(version string) (string, error) {
	v, err := semver.ParseTolerant(version)
	if err != nil {
		return "", errors.New("module does not have semver compatible version")
	}

	// psuedoversions are commits that don't have a corresponding tag at the specified git hash
	// https://golang.org/cmd/go/#hdr-Pseudo_versions
	// pulumi-aws v1.29.1-0.20200403140640-efb5e2a48a86 (first commit after 1.29.0 release)
	if buildutil.IsPseudoVersion(version) {
		// no prior tag means there was never a release build
		if v.Major == 0 && v.Minor == 0 && v.Patch == 0 {
			return "", errors.New("invalid pseduoversion with no prior tag")
		}
		// patch is typically bumped from the previous tag when using pseudo version
		// downgrade the patch by 1 to make sure we match a release that exists
		patch := v.Patch
		if patch > 0 {
			patch--
		}
		version = fmt.Sprintf("v%v.%v.%v", v.Major, v.Minor, patch)
	}

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Check go.mod for a `replace` directive pointing the provider at a local directory and pin a tagged version instead.
  2. Ensure the provider module has a valid semver git tag (e.g. v1.29.1) and re-run `go mod tidy`.
  3. If pulumi-plugin.json in the provider module sets a Version, make it valid semver.
  4. Use a pseudo-version pin (`go get module@commit`) rather than an untagged branch reference, so a parseable version resolves.

Example fix

// before (go.mod)
replace github.com/pulumi/pulumi-aws/sdk => ../pulumi-aws/sdk
// after
require github.com/pulumi/pulumi-aws/sdk v1.29.1
Defensive patterns

Strategy: validation

Validate before calling

// shell, before pulumi up
ver=$(go list -m -f '{{.Version}}' github.com/pulumi/pulumi-aws/sdk)
semver_regex='^v?[0-9]+\.[0-9]+\.[0-9]+'
echo "$ver" | grep -Eq "$semver_regex" || echo "non-semver version: $ver"

Prevention

When it happens

Trigger: GetRequiredPackages -> getPackage -> normalizeVersion: m.Version (or pulumi-plugin.json Version, if set) cannot be parsed by semver.ParseTolerant.

Common situations: A pulumi provider dependency replaced with a local path (go.mod `replace` directive) so no version exists; a module fetched by branch/commit without tags; pulumi-plugin.json containing a non-semver Version like "main" or "latest".

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/605c6ba90e1b54da. Report an issue: GitHub.