goreleaser/goreleaser · error

invalid goos: %s

Error message

invalid goos: %s

What it means

listTargets validates every computed build target's GOOS against the list of valid Go operating systems (validGoos). This error means a target's goos value is not a real Go-supported OS, so the build would fail later. It is a configuration validation error thrown early by the golang builder.

Source

Thrown at internal/builders/golang/targets.go:115

		"GOMIPS=" + t.Gomips,
		"GOMIPS64=" + t.Gomips,
		"GOPPC64=" + t.Goppc64,
		"GORISCV64=" + t.Goriscv64,
	}
}

func listTargets(build config.Build) ([]string, error) {
	//nolint:prealloc
	var targets []Target
	//nolint:prealloc
	var result []string
	built, err := allBuildTargets(build)
	if err != nil {
		return result, err
	}
	for _, target := range built {
		if !slices.Contains(validGoos, target.Goos) {
			return result, fmt.Errorf("invalid goos: %s", target.Goos)
		}
		if !slices.Contains(validGoarch, target.Goarch) {
			return result, fmt.Errorf("invalid goarch: %s", target.Goarch)
		}
		if target.Goamd64 != "" && !slices.Contains(validGoamd64, target.Goamd64) {
			return result, fmt.Errorf("invalid goamd64: %s", target.Goamd64)
		}
		if target.Go386 != "" && !slices.Contains(validGo386, target.Go386) {
			return result, fmt.Errorf("invalid go386: %s", target.Go386)
		}
		if target.Goarm64 != "" && !validGoarm64.MatchString(target.Goarm64) {
			return result, fmt.Errorf("invalid goarm64: %s", target.Goarm64)
		}
		if target.Gomips != "" && !slices.Contains(validGomips, target.Gomips) {
			return result, fmt.Errorf("invalid gomips: %s", target.Gomips)
		}
		if target.Goppc64 != "" && !slices.Contains(validGoppc64, target.Goppc64) {
			return result, fmt.Errorf("invalid goppc64: %s", target.Goppc64)

View on GitHub (pinned to f5edd73956)

Solutions

  1. Fix the `goos` entries in the build config, using valid values: aix, android, darwin, dragonfly, freebsd, illumos, ios, js, linux, netbsd, openbsd, plan9, solaris, wasip1, windows
  2. Run `go tool dist list` to see all valid GOOS/GOARCH pairs
  3. Check for typos (e.g. `linuxs` → `linux`, `macos` → `darwin`)
  4. Run `goreleaser check` to validate the config before releasing

Example fix

// .goreleaser.yaml
// before
builds:
  - goos: [macos, linux]
// after
builds:
  - goos: [darwin, linux]
Defensive patterns

Strategy: validation

Validate before calling

var validGoos = map[string]bool{
    "aix": true, "android": true, "darwin": true, "dragonfly": true,
    "freebsd": true, "illumos": true, "ios": true, "js": true,
    "linux": true, "netbsd": true, "openbsd": true, "plan9": true,
    "solaris": true, "wasip1": true, "windows": true,
}
for _, goos := range cfg.Builds[0].Goos {
    if !validGoos[goos] {
        return fmt.Errorf("invalid goos %q", goos)
    }
}

Prevention

When it happens

Trigger: Setting an unknown `goos` in a build's targets/overrides (e.g. a typo like `goos: linuxs` or `macos` instead of `darwin`) so the resolved target contains an invalid GOOS.

Common situations: Typos in .goreleaser.yaml goos lists; using an OS name that Go does not support (e.g. `windowsphone`, `ios` misuse); copy-pasting OS names from other tooling with different naming conventions.

Related errors


AI-assisted analysis of goreleaser/goreleaser@f5edd73956 (2026-09-05). Data as JSON: /api/errors/1206dffbcf0e12da. Report an issue: GitHub.