golang/go · error
could not map %s symbol with no section
Error message
could not map %s symbol with no section
What it means
`mapToPESection` places a symbol into the PE (Windows) output by reading its associated section (`ldr.SymSect(s)`). If a symbol that needs a PE section mapping has a `nil` section, the linker has no way to compute its file offset and aborts. This typically indicates an internal inconsistency: a symbol reached the PE symbol table without ever being assigned to an output section.
Source
Thrown at src/cmd/link/internal/ld/pe.go:850
out.WriteStringN(name, 8)
}
out.Write32(uint32(value))
out.Write16(uint16(sectidx))
out.Write16(typ)
out.Write8(class)
out.Write8(0) // no aux entries
ldr.SetSymDynid(s, int32(f.symbolCount))
f.symbolCount++
}
// mapToPESection searches peFile f for s symbol's location.
// It returns PE section index, and offset within that section.
func (f *peFile) mapToPESection(ldr *loader.Loader, s loader.Sym, linkmode LinkMode) (pesectidx int, offset int64, err error) {
sect := ldr.SymSect(s)
if sect == nil {
return 0, 0, fmt.Errorf("could not map %s symbol with no section", ldr.SymName(s))
}
if sect.Seg == &Segtext {
return f.textSect.index, int64(uint64(ldr.SymValue(s)) - Segtext.Vaddr), nil
}
if sect.Seg == &Segrodata {
return f.rdataSect.index, int64(uint64(ldr.SymValue(s)) - Segrodata.Vaddr), nil
}
if sect.Seg != &Segdata {
return 0, 0, fmt.Errorf("could not map %s symbol with non .text or .rdata or .data section", ldr.SymName(s))
}
v := uint64(ldr.SymValue(s)) - Segdata.Vaddr
if linkmode != LinkExternal {
return f.dataSect.index, int64(v), nil
}
if ldr.SymType(s).IsDATA() {
return f.dataSect.index, int64(v), nil
}
// Note: although address of runtime.edata (type sym.SDATA) is at the start of .bss sectionView on GitHub (pinned to b6b368adc5)
Solutions
- `go clean -cache && go build -a` to eliminate stale/inconsistent objects.
- Confirm every exported (`//export`) symbol has a definition compiled in under the current build tags.
- Update to a current Go release if hitting this on an older version — several such inconsistencies were fixed.
- Reduce the reproducer and file a Go bug with the symbol name from the error message.
Defensive patterns
Strategy: validation
Validate before calling
# Verify every //export symbol has a compiled definition
for pkg in $(go list ./...); do
grep -rn '^//export' "$(go list -f '{{.Dir}}' "$pkg")" 2>/dev/null | while read -r line; do
sym=$(echo "$line" | sed 's/.*\/\/export //')
go tool nm bin/app 2>/dev/null | grep -q " $sym$" || echo "exported symbol missing: $sym"
done
done Try / catch
set +e go build ./... rc=$? set -e if [ $rc -ne 0 ]; then go clean -cache && go build -a ./... fi
Prevention
- Ensure every `//export` symbol's package is included under the active build tags.
- Pin a single Go toolchain version for all objects.
- Run `go clean -cache` after a Go upgrade before Windows/cgo builds.
- Upgrade Go — several PE section-mapping bugs were fixed.
When it happens
Trigger: Exporting (`-ldflags='-H windowsgui'` plus `//export`) a symbol that was never defined or was dead-code-eliminated; cgo on Windows referencing an undefined external symbol; a linker bug where a symbol's section was not set during layout; mixing objects from incompatible Go versions in one binary.
Common situations: Cross-compiling for Windows from a non-Windows host with mismatched toolchain/cache; exporting a symbol from a package whose build tags excluded its definition; corrupt build cache after a Go upgrade.
Related errors
- could not map %s symbol with non .text or .rdata or .data se
- dynamic relocation to unreachable symbol %s
- 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
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/1f38056b1491bfea.
Report an issue: GitHub.