golang/go · critical
internal error in windynrelocsym: unsupported arch %v
Error message
internal error in windynrelocsym: unsupported arch %v
What it means
An internal error in windynrelocsym during PE import JMP stub code generation. The switch on ctxt.Arch.Family generates architecture-specific JMP instructions (e.g. jmp *addr). If the architecture family is not one of the supported cases (sys.I386, sys.AMD64, and potentially others), the default branch rejects it. This code path is Windows-specific and only runs for architectures where PE dynamic imports are implemented.
Source
Thrown at src/cmd/link/internal/ld/data.go:898
// Consistency check: don't want to see both PLT and GOT tokens.
if tgot != -1 {
return fmt.Errorf("internal error in windynrelocsym: invalid GOT setting %d for reloc to %s", tgot, ctxt.loader.SymName(targ))
}
// make dynimport JMP table for PE object files.
tplt := int32(rel.Size())
ctxt.loader.SetPlt(targ, tplt)
if su == nil {
su = ctxt.loader.MakeSymbolUpdater(s)
}
r.SetSym(rel.Sym())
r.SetAdd(int64(tplt))
// jmp *addr
switch ctxt.Arch.Family {
default:
return fmt.Errorf("internal error in windynrelocsym: unsupported arch %v", ctxt.Arch.Family)
case sys.I386:
rel.AddUint8(0xff)
rel.AddUint8(0x25)
rel.AddAddrPlus(ctxt.Arch, targ, 0)
rel.AddUint8(0x90)
rel.AddUint8(0x90)
case sys.AMD64:
// The relocation symbol might be at an absolute offset
// higher than 32 bits, but the jump instruction can't
// encode more than 32 bit offsets. We use a jump
// relative to the instruction pointer to get around this
// limitation.
rel.AddUint8(0xff)
rel.AddUint8(0x25)
rel.AddPCRelPlus(ctxt.Arch, targ, 0)
rel.AddUint8(0x90)
rel.AddUint8(0x90)
case sys.ARM64:View on GitHub (pinned to b6b368adc5)
Solutions
- Verify the target GOARCH is supported for Windows PE dynamic linking in your Go version
- Check Go release notes for architecture support status
- Use a Go version that supports the target architecture
- If the architecture should be supported, report at https://github.com/golang/go/issues
- Fall back to -linkmode=external if the external linker supports the architecture
Defensive patterns
Strategy: fallback
Validate before calling
// Check architecture support for PE dynamic imports before building
func isArchSupportedForPEDynImport(family sys.ArchFamily) bool {
switch family {
case sys.I386, sys.AMD64:
return true
// Add ARM64 if supported by your Go version
default:
return false
}
} Try / catch
// Fall back to external linker for unsupported architectures
if !isArchSupportedForPEDynImport(ctxt.Arch.Family) {
log.Printf("PE dynamic imports not supported on %v, using external linker", ctxt.Arch.Family)
return useExternalLinker()
} Prevention
- Verify GOARCH is supported for Windows PE dynamic linking in your Go version
- Check Go release notes for Windows architecture support status
- Use -linkmode=external if the internal linker lacks architecture support for PE imports
When it happens
Trigger: windynrelocsym generates a JMP stub for a PE import. The switch on ctxt.Arch.Family hits the default case, meaning the architecture is not supported for PE import stub generation. This could occur if a new Windows architecture is being targeted but the stub generator has not been updated.
Common situations: Building for a Windows architecture that lacks PE import stub support (e.g. experimental GOARCH values); a misconfigured cross-compilation environment; using a Go version that does not yet support the target architecture for PE dynamic linking.
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
- dynamic relocation to unreachable symbol %s
- cannot find .data
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/88d80448d17f2fe0.
Report an issue: GitHub.