golang/go · error

corrupt pointer found in go:fipsinfo

Error message

corrupt pointer found in go:fipsinfo

What it means

During PE FIPS post-link processing, the code derives a self-pointer from the PE section's VirtualAddress plus the scan offset, then performs a sanity check: the low 12 bits (virtual page offset) of the computed self-address must match the low 12 bits of the scan offset. If they differ, the pointer is considered corrupt, indicating a mismatch between the PE layout and the fipsinfo data.

Source

Thrown at src/cmd/link/internal/ld/fips140.go:570

	//	.data (file) Size = 0x1fc00
	//	go:fipsinfo found at offset 0x2ac5e0 (off=0x1e0)
	//	go:fipsinfo self pointer = 0x01402af1e0
	//
	// From the section headers, the address of the go:fipsinfo symbol
	// should be 0x2af000 + (0x2ac5e0 - 0x2ac400) = 0x2af1e0,
	// yet in this case its pointer is 0x1402af1e0, meaning the
	// data section's VirtualAddress is really 0x1402af000.
	// This is not (only) a 32-bit truncation problem, since the uint32
	// truncation of that address would be 0x402af000, not 0x2af000.
	// Perhaps there is some 64-bit extension that debug/pe is not
	// reading or is misreading. In any event, we can derive the delta
	// between computed VirtualAddress and listed VirtualAddress
	// and apply it to the rest of the pointers.
	// As a sanity check, the low 12 bits (virtual page offset)
	// must match between our computed address and the actual one.
	peself := int64(sect.VirtualAddress) + off
	if self&0xfff != off&0xfff {
		return fmt.Errorf("corrupt pointer found in go:fipsinfo")
	}
	delta := peself - self

Addrs:
	for i := 0; i < 4; i++ {
		start := int64(uptr(data[0:])) + delta
		end := int64(uptr(data[ctxt.Arch.PtrSize:])) + delta
		data = data[2*ctxt.Arch.PtrSize:]
		for _, sect := range pf.Sections {
			if int64(sect.VirtualAddress) <= start && start <= end && end <= int64(sect.VirtualAddress)+int64(sect.Size) {
				off := int64(sect.Offset) - int64(sect.VirtualAddress)
				if err := f.addSection(start+off, end+off); err != nil {
					return err
				}
				continue Addrs
			}
		}
		return fmt.Errorf("invalid pointers found in go:fipsinfo")

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Clean rebuild: go clean -cache && GOFIPS=1 go build
  2. Report as a Go linker bug at https://github.com/golang/go/issues with the binary and PE section details
  3. Check if the PE binary uses large-image (>4GB virtual address) layout that may confuse debug/pe
  4. Verify no post-build tools (editbin, PE rewriters) modified section addresses
  5. Try a different Go version — this may be fixed in newer releases that handle 64-bit PE addresses
Defensive patterns

Strategy: fallback

Try / catch

// Handle corrupt pointer with diagnostic context
if self&0xfff != off&0xfff {
    return fmt.Errorf("corrupt pointer in go:fipsinfo (PE VA=%#x, off=%#x) — try clean rebuild or report Go bug", sect.VirtualAddress, off)
}

Prevention

When it happens

Trigger: peself is computed as int64(sect.VirtualAddress) + off. The code checks self & 0xfff != off & 0xfff. If the page-offset bits don't align, the error fires. This can happen when the PE VirtualAddress has unexpected high bits (as noted in the source comments about 64-bit extension issues in debug/pe) or when the delta between computed and actual addresses breaks the low-bit invariant.

Common situations: A bug in Go's debug/pe library that misreads VirtualAddress for large 64-bit addresses (as noted in the source comments about 0x1402af1e0 addresses); unusual PE section alignment; binary modified by tools that change section virtual addresses; mismatch between the linker's PE writer and the post-link reader's address interpretation.

Related errors


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