golang/go · error

invalid linkmode

Error message

invalid linkmode: %q

What it means

The Go linker's LinkMode.Set method rejects an unrecognized -linkmode flag value. LinkMode controls whether the internal or external linker is used for the final link step. Valid values are: auto (let the linker decide), internal (use Go's internal linker), and external (use the system's external linker such as gcc or clang).

Solutions

  1. Use one of the three valid values: auto, internal, or external
  2. Check the flag is passed correctly: go build -ldflags='-linkmode=external'
  3. If unsure which to use, omit the flag entirely (defaults to auto)
  4. Validate the linkmode in build scripts before passing to the linker

Example fix

# before
go build -ldflags='-linkmode=pie' main.go

# after
go build -ldflags='-linkmode=external' main.go
Defensive patterns

Strategy: validation

Validate before calling

// Validate linkmode before passing to linker
var validLinkModes = map[string]bool{
    "auto": true, "internal": true, "external": true,
}

func validateLinkMode(s string) error {
    if !validLinkModes[s] {
        return fmt.Errorf("invalid linkmode %q; valid: auto, internal, external", s)
    }
    return nil
}

Try / catch

// Handle linkmode errors gracefully
if err := linkMode.Set(s); err != nil {
    fmt.Fprintf(os.Stderr, "Error: %v\nValid linkmodes: auto, internal, external\n", err)
    os.Exit(1)
}

Prevention

When it happens

Trigger: The flag.Value Set method is called by the flag parser with the -linkmode argument. If the string does not match 'auto', 'internal', or 'external', the default branch returns this error.

Common situations: Typo in linkmode name; using a linkmode value from documentation that has been renamed; passing the value through ldflags incorrectly; build scripts that construct ldflags dynamically with an unvalidated variable.

Related errors


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

Appendix: source

Thrown at src/cmd/link/internal/ld/config.go:93

	case BuildModePlugin:
		return "plugin"
	}
	return fmt.Sprintf("BuildMode(%d)", uint8(mode))
}

// LinkMode indicates whether an external linker is used for the final link.
type LinkMode uint8

const (
	LinkAuto LinkMode = iota
	LinkInternal
	LinkExternal
)

func (mode *LinkMode) Set(s string) error {
	switch s {
	default:
		return fmt.Errorf("invalid linkmode: %q", s)
	case "auto":
		*mode = LinkAuto
	case "internal":
		*mode = LinkInternal
	case "external":
		*mode = LinkExternal
	}
	return nil
}

func (mode *LinkMode) String() string {
	switch *mode {
	case LinkAuto:
		return "auto"
	case LinkInternal:
		return "internal"
	case LinkExternal:
		return "external"

View on GitHub (pinned to b6b368adc5)