golang/go · error

dynamic relocation to unreachable symbol %s

Error message

dynamic relocation to unreachable symbol %s

What it means

During Windows PE dynamic relocation processing in windynrelocsym, this error fires when a relocation references a symbol that the linker's reachability analysis has marked as unreachable (dead-code eliminated) and the relocation is not weak. An unreachable symbol should not have live relocations pointing to it; this condition indicates a mismatch between the reachability pass and the relocation pass.

Source

Thrown at src/cmd/link/internal/ld/data.go:849

// Note that for a given symbol (as above) it is perfectly legal to
// have both direct and indirect references.
func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) error {
	var su *loader.SymbolBuilder
	relocs := ctxt.loader.Relocs(s)
	for ri := 0; ri < relocs.Count(); ri++ {
		r := relocs.At(ri)
		if r.IsMarker() {
			continue // skip marker relocations
		}
		targ := r.Sym()
		if targ == 0 {
			continue
		}
		if !ctxt.loader.AttrReachable(targ) {
			if r.Weak() {
				continue
			}
			return fmt.Errorf("dynamic relocation to unreachable symbol %s",
				ctxt.loader.SymName(targ))
		}
		tgot := ctxt.loader.SymGot(targ)
		if tgot == loadpe.RedirectToDynImportGotToken {

			// Consistency check: name should be __imp_X
			sname := ctxt.loader.SymName(targ)
			if !strings.HasPrefix(sname, "__imp_") {
				return fmt.Errorf("internal error in windynrelocsym: redirect GOT token applied to non-import symbol %s", sname)
			}

			// Locate underlying symbol (which originally had type
			// SDYNIMPORT but has since been retyped to SWINDOWS).
			ds, err := loadpe.LookupBaseFromImport(targ, ctxt.loader, ctxt.Arch)
			if err != nil {
				return err
			}
			dstyp := ctxt.loader.SymType(ds)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Try switching to external linking: go build -ldflags='-linkmode=external'
  2. Clean rebuild: go clean -cache && go build
  3. Report as a Go linker bug at https://github.com/golang/go/issues with GOOS=windows and the buildmode
  4. If using CGO, check for symbol visibility issues in C/C++ dependencies
  5. Try disabling dead code elimination to isolate the issue
Defensive patterns

Strategy: fallback

Try / catch

// In linker driver code, catch internal relocation errors
// and fall back to external linking
if err := windynrelocsym(ctxt, s, r, ri); err != nil {
    if !externalLinking {
        log.Printf("internal link failed (%v), retrying with -linkmode=external", err)
        return retryWithExternalLinker()
    }
    return err
}

Prevention

When it happens

Trigger: The function iterates relocations for a symbol, calls ctxt.loader.AttrReachable(targ) on each relocation target. If the target is unreachable and r.Weak() is false, the error is returned with the symbol name. Marker relocations and zero-target relocations are skipped before this check.

Common situations: Building a Windows DLL or c-shared binary where CGO dependencies reference symbols that the linker incorrectly garbage-collected; a bug in the dead-code elimination pass that marks a needed symbol as unreachable; mixed object files from different compilation stages with inconsistent reachability metadata.

Related errors


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