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

  1. Verify the target GOARCH is supported for Windows PE dynamic linking in your Go version
  2. Check Go release notes for architecture support status
  3. Use a Go version that supports the target architecture
  4. If the architecture should be supported, report at https://github.com/golang/go/issues
  5. 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

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


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