hashicorp/nomad · error

unexpected envoy version format

Error message

unexpected envoy version format: %w

What it means

The semver helper normalizes the chosen Envoy version string using hashicorp/go-version. Version strings without a leading 'v' and unofficial 3-number tags are tolerated by design, but if version.NewVersion(chosen) fails outright, the version format is unrecognized and this error is returned (later wrapped by tweakImage callers).

Solutions

  1. Check the wrapped error text to see the offending version string from Consul.
  2. Set an explicit, semver-parsable image (e.g. envoyproxy/envoy:v1.28.0) so the hook doesn't need to interpolate.
  3. Upgrade Nomad (and/or Consul) if the reported version uses a format your Nomad version can't parse.
  4. If running unofficial Envoy images, tag them as plain x.y.z (three numbers, optional 'v' prefix).

Example fix

// before
image: "envoyproxy/envoy:latest"
// after
image: "envoyproxy/envoy:v1.28.0"
Defensive patterns

Strategy: type-guard

Validate before calling

import "github.com/hashicorp/go-version"
// validate any custom envoy version string before using it in an image
if _, err := version.NewVersion(strings.TrimPrefix(chosen, "v")); err != nil {
    return fmt.Errorf("invalid envoy version %q", chosen)
}

Type guard

func isEnvoySemver(s string) bool {
    _, err := version.NewVersion(strings.TrimPrefix(s, "v"))
    return err == nil
}

Try / catch

image, err := tweakImage(taskImage, proxies)
if err != nil {
    var verErr error
    if errors.As(err, &verErr) && strings.Contains(err.Error(), "unexpected envoy version format") {
        image = fallbackEnvoyImage // e.g. envoyproxy/envoy:v1.28.0
    }
}

Prevention

When it happens

Trigger: version.NewVersion(chosen) errors inside semver — chosen is empty, contains non-numeric/prerelease garbage, or a string like 'latest'/'stable' instead of a version like '1.28.0' or 'v1.28.0'.

Common situations: Consul reporting an unexpected or empty Envoy version; job image template interpolating to 'latest' or a digest; custom/enterprise Envoy image tags that aren't numeric versions; regression from Consul returning a new version scheme the Nomad version doesn't parse.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/03be448710b47caa. Report an issue: GitHub.

Appendix: source

Thrown at client/allocrunner/taskrunner/envoy_version_hook.go:196

	latest, err := semver(versions[0])
	if err != nil {
		return "", err
	}

	return strings.ReplaceAll(configured, envoy.VersionVar, latest), nil
}

// semver sanitizes the envoy version string coming from Consul into the format
// used by the Envoy project when publishing images (i.e. proper semver). This
// resulting string value does NOT contain the 'v' prefix for 2 reasons:
//  1. the version library does not include the 'v'
//  2. its plausible unofficial images use the 3 numbers without the prefix for
//     tagging their own images
func semver(chosen string) (string, error) {
	v, err := version.NewVersion(chosen)
	if err != nil {
		return "", fmt.Errorf("unexpected envoy version format: %w", err)
	}
	return v.String(), nil
}

View on GitHub (pinned to 482b49bf1a)