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
- Try switching to external linking: go build -ldflags='-linkmode=external'
- Clean rebuild: go clean -cache && go build
- Report as a Go linker bug at https://github.com/golang/go/issues with GOOS=windows and the buildmode
- If using CGO, check for symbol visibility issues in C/C++ dependencies
- 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
- Keep -linkmode=external as a fallback for Windows PE builds
- Ensure CGO dependencies export symbols correctly (no hidden visibility issues)
- Clean build cache when encountering unexpected reachability errors
- Report persistent occurrences as Go linker bugs
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
- internal error in windynrelocsym: redirect GOT token applied
- internal error in windynrelocsym: underlying sym for %q has
- internal error in windynrelocsym: invalid GOT setting %d for
- internal error in windynrelocsym: unsupported arch %v
- cannot find .data
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/66b8ab2645170a27.
Report an issue: GitHub.