vitessio/vitess · error

golang version malformatted: %s

Error message

golang version malformatted: %s

What it means

getLatestStableGolangReleases fetches Go release metadata (from the Go.dev releases API) and parses each stable release's version string, which should start with the prefix "go" (e.g. go1.22.5). If a stable release version string lacks that prefix, the tool treats it as malformed and aborts with this error.

Source

Thrown at go/tools/go-upgrade/go-upgrade.go:337

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	var latestGoReleases []latestGolangRelease
	err = json.Unmarshal(body, &latestGoReleases)
	if err != nil {
		return nil, err
	}

	var versions version.Collection
	for _, release := range latestGoReleases {
		if !release.Stable {
			continue
		}
		if !strings.HasPrefix(release.Version, "go") {
			return nil, fmt.Errorf("golang version malformatted: %s", release.Version)
		}
		newVersion, err := version.NewVersion(release.Version[2:])
		if err != nil {
			return nil, err
		}
		versions = append(versions, newVersion)
	}
	return versions, nil
}

// chooseNewVersion decides what will be the next version we're going to use in our codebase.
// Given the current Golang version, the available latest versions and whether we allow major upgrade or not,
// chooseNewVersion will return either the new version or nil if we cannot/don't need to upgrade.
func chooseNewVersion(curVersion *version.Version, latestVersions version.Collection, allowMajorUpgrade bool) *version.Version {
	selectedVersion := curVersion
	for _, latestVersion := range latestVersions {
		if !allowMajorUpgrade && !isSameMajorMinorVersion(latestVersion, selectedVersion) {
			continue

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Inspect the raw releases API response (https://go.dev/dl/?mode=json) for entries whose version lacks the 'go' prefix
  2. If the API format changed, update getLatestStableGolangReleases to parse the new format
  3. Check for proxies/HTTP overrides altering the response and bypass them
  4. Retry later if it's a transient upstream data issue

Example fix

// before
if !strings.HasPrefix(release.Version, "go") {
    return nil, fmt.Errorf("golang version malformatted: %s", release.Version)
}
// after
if !strings.HasPrefix(release.Version, "go") {
    log.Warn("skipping unexpected release version", slog.Any("version", release.Version))
    continue
}
Defensive patterns

Strategy: fallback

Validate before calling

for _, r := range releases {
    if r.Stable && !strings.HasPrefix(r.Version, "go") {
        log.Warn("unexpected release entry, skipping", slog.Any("version", r.Version))
    }
}

Type guard

func isWellFormedGoRelease(v string) bool {
    return strings.HasPrefix(v, "go") && len(v) > 2
}

Try / catch

releases, err := getLatestStableGolangReleases()
if err != nil {
    return fmt.Errorf("go.dev releases API returned unexpected data; retry or fall back to current version: %w", err)
}

Prevention

When it happens

Trigger: The releases API response contains a stable release whose Version field doesn't start with "go" — typically due to an API response format change or unexpected entry.

Common situations: Upstream Go.dev API schema change; a proxy/mirror returning altered release metadata; network middleware rewriting the response; running with a cached or mocked fixture that has non-"go"-prefixed versions.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/171f7bbf66690360. Report an issue: GitHub.