gohugoio/hugo · error

failed to execute 'go %v': %s %T

Error message

failed to execute 'go %v': %s %T

What it means

Hugo's module Client wraps the Go toolchain (`go get`, `go mod download`, etc.) to manage Hugo Modules. In `runGo` (modules/client.go:811), if `cmd.Run()` fails with an error that is NOT an `*exec.ExitError` (i.e. the process could not even be started or was killed abnormally, rather than exiting with a non-zero status), Hugo reports this error including the args, the error text, and its Go type. Notably, `exec.ErrNotFound` (go binary missing) is handled separately and silently tolerated, so this path means something more unusual prevented execution.

Source

Thrown at modules/client.go:811

			c.goBinaryStatus = goBinaryStatusNotFound
			return nil
		}

		if strings.Contains(stderr.String(), "invalid version: unknown revision") {
			// See https://github.com/gohugoio/hugo/issues/6825
			c.logger.Println(`An unknown revision most likely means that someone has deleted the remote ref (e.g. with a force push to GitHub).
To resolve this, you need to manually edit your go.mod file and replace the version for the module in question with a valid ref.

The easiest is to just enter a valid branch name there, e.g. master, which would be what you put in place of 'v0.5.1' in the example below.

require github.com/gohugoio/hugo-mod-jslibs/instantpage v0.5.1

If you then run 'hugo mod graph' it should resolve itself to the most recent version (or commit if no semver versions are available).`)
		}

		_, ok := err.(*exec.ExitError)
		if !ok {
			return fmt.Errorf("failed to execute 'go %v': %s %T", args, err, err)
		}

		// Too old Go version
		if strings.Contains(stderr.String(), "flag provided but not defined") {
			c.goBinaryStatus = goBinaryStatusTooOld
			return nil
		}

		return fmt.Errorf("go command failed: %s", stderr)

	}

	return nil
}

var goOutputReplacer = strings.NewReplacer(
	"go: to add module requirements and sums:", "hugo: to add module requirements and sums:",
	"go mod tidy", "hugo mod tidy",

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Run `go version` in the same shell/environment Hugo uses to confirm the binary starts at all.
  2. Check the %T type printed in the message — a context error means a timeout/cancellation; *fs.PathError or permission errors point at the binary or working dir.
  3. Verify the go binary permissions and that it matches the host architecture (e.g. amd64 binary on arm64).
  4. Check hexec security config (`security.exec.allow`) permits `go`.
  5. Reinstall Go or fix PATH if the binary is a broken symlink.

Example fix

# before: broken symlink
ls -l $(which go)  # -> dangling link
# after: reinstall and verify
sudo rm /usr/local/bin/go
export PATH=/usr/local/go/bin:$PATH
go version && hugo mod tidy
Defensive patterns

Strategy: validation

Validate before calling

if _, err := exec.LookPath("go"); err != nil {
    return fmt.Errorf("go binary not found in PATH; Hugo Modules require Go: %w", err)
}

Try / catch

if err := client.Get(args...); err != nil {
    if strings.Contains(err.Error(), "failed to execute") {
        // go toolchain missing or broken environment
    }
    return err
}

Prevention

When it happens

Trigger: Any `hugo mod` command (get, tidy, graph, vendor, verify) or a build that resolves Hugo Modules, when the `go` process fails to launch or dies without a normal exit status: permission denied on the go binary, context cancellation/timeout via `hexec.WithContext`, an invalid working directory passed via `WithDir`, or the process being killed by the OS (OOM, signal).

Common situations: A `go` on PATH that is not executable or is a broken shim/symlink; CI containers with a corrupt Go install; security policies (hexec allowlist) blocking execution; Hugo's working directory deleted mid-build; the process killed by an OOM killer in constrained CI runners.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/eba90a67ef3c9bc1.json. Report an issue: GitHub ↗.