golang/go · error

unsupported GOOS/GOARCH pair

Error message

unsupported GOOS/GOARCH pair %s/%s

What it means

CheckGOOSARCHPair returns this when platform.BuildModeSupported reports that the (compiler, "default", goos, goarch) tuple has no support. It gates cross-compilation targets: only GOOS/GOARCH pairs the toolchain was built to know about are allowed.

Solutions

  1. Run 'go tool dist list' to see supported pairs and copy the exact spelling.
  2. Install a Go toolchain that includes the desired port (some ports are gated by build tags or require gccgo).
  3. For gccgo-only targets, build with -compiler=gccgo (CheckGOOSARCHPair queries the configured compiler).
  4. Check for typos: GOARCH values are lowercase, GOOS too.

Example fix

// before
$ GOOS=linux GOARCH=x86_64 go build
// error: unsupported GOOS/GOARCH pair linux/x86_64

// after — use the correct GOARCH token
$ GOOS=linux GOARCH=amd64 go build
Defensive patterns

Strategy: validation

Validate before calling

// Confirm a GOOS/GOARCH pair is supported before building.
func checkPair(goos, goarch string) error {
    out, err := exec.Command("go", "tool", "dist", "list").Output()
    if err != nil { return err }
    want := goos + "/" + goarch + "\n"
    if !bytes.Contains(out, []byte(want)) {
        return fmt.Errorf("%s is not a supported GOOS/GOARCH pair", want)
    }
    return nil
}

Prevention

When it happens

Trigger: Calling CheckGOOSARCHPair (used by 'go build/env/list' target validation, CGO cross-compile setup, and platform checks) with a pair the installed Go toolchain doesn't ship — e.g. GOIOS=arm64 with a non-darwin GOARCH, or a misspelled GOARCH like 'amd64x'.

Common situations: Typos in GOOS/GOARCH env vars; targeting a pair that requires a separate Go installation (e.g. wasi or a custom platform); mixing GOARCH=mips with a gc toolchain that lacks that port.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/19a8c22415af6715. Report an issue: GitHub.

Appendix: source

Thrown at src/cmd/go/internal/work/action.go:377

func closeBuilders() {
	leakedBuilders := 0
	builderWorkDirs.Range(func(bi, _ any) bool {
		leakedBuilders++
		if err := bi.(*Builder).Close(); err != nil {
			base.Error(err)
		}
		return true
	})

	if leakedBuilders > 0 && base.GetExitStatus() == 0 {
		fmt.Fprintf(os.Stderr, "go: internal error: Builder leaked on successful exit\n")
		base.SetExitStatus(1)
	}
}

func CheckGOOSARCHPair(goos, goarch string) error {
	if !platform.BuildModeSupported(cfg.BuildContext.Compiler, "default", goos, goarch) {
		return fmt.Errorf("unsupported GOOS/GOARCH pair %s/%s", goos, goarch)
	}
	return nil
}

// NewObjdir returns the name of a fresh object directory under b.WorkDir.
// It is up to the caller to call b.Mkdir on the result at an appropriate time.
// The result ends in a slash, so that file names in that directory
// can be constructed with direct string addition.
//
// NewObjdir must be called only from a single goroutine at a time,
// so it is safe to call during action graph construction, but it must not
// be called during action graph execution.
func (b *Builder) NewObjdir() string {
	b.objdirSeq++
	return str.WithFilePathSeparator(filepath.Join(b.WorkDir, fmt.Sprintf("b%03d", b.objdirSeq)))
}

// readpkglist returns the list of packages that were built into the shared library

View on GitHub (pinned to b6b368adc5)