golang/go · error

missing __DWARF segment

Error message

missing __DWARF segment

What it means

In the combine-DWARF flow, after opening the DWARF file (produced by `dsymutil`), the linker looks for a `__DWARF` segment to copy into the executable. If `dsymutil` produced no DWARF (e.g. it was run on a binary with no debug info, or failed silently and emitted an empty file), there is nothing to merge and the link aborts.

Source

Thrown at src/cmd/link/internal/ld/macho_combine_dwarf.go:93

	// The string table needs to be the last thing in the file
	// for code signing to work. So we'll need to move the
	// linkedit section, but all the others can be copied directly.
	linkseg := exem.Segment("__LINKEDIT")
	if linkseg == nil {
		return fmt.Errorf("missing __LINKEDIT segment")
	}

	if _, err := exef.Seek(0, 0); err != nil {
		return err
	}
	if _, err := io.CopyN(outf, exef, int64(linkseg.Offset)); err != nil {
		return err
	}

	realdwarf := dwarfm.Segment("__DWARF")
	if realdwarf == nil {
		return fmt.Errorf("missing __DWARF segment")
	}

	// Try to compress the DWARF sections. This includes some Apple
	// proprietary sections like __apple_types.
	compressedSects, compressedBytes, err := machoCompressSections(ctxt, dwarfm)
	if err != nil {
		return err
	}

	// Now copy the dwarf data into the output.
	// Kernel requires all loaded segments to be page-aligned in the file,
	// even though we mark this one as being 0 bytes of virtual address space.
	dwarfstart := Rnd(int64(linkseg.Offset), *FlagRound)
	if _, err := outf.Seek(dwarfstart, 0); err != nil {
		return err
	}

	if _, err := dwarff.Seek(int64(realdwarf.Offset), 0); err != nil {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Keep debug info through link (`-ldflags='-s -w'` must be removed if you want DWARF).
  2. Ensure `dsymutil` runs on the unstripped binary and produces a `.dSYM` with a `__DWARF` segment (`dwarfdump --uuid out.dSYM`).
  3. Pass the `.dSYM` DWARF file (not the executable) to the combine step.

Example fix

# before: stripped binary yields no __DWARF in dSYM
go build -ldflags='-s -w' -o bin/app ./...
dsymutil bin/app

# after
go build -o bin/app ./...
dsymutil bin/app -o bin/app.dSYM
Defensive patterns

Strategy: validation

Validate before calling

# Confirm the dSYM has a __DWARF segment before combining
DSYM=bin/app.dSYM/Contents/Resources/DWARF/app
test -f "$DSYM" && dwarfdump --uuid "$DSYM" >/dev/null 2>&1 && echo 'DWARF present' || echo 'no DWARF; rebuild without -s -w'

Try / catch

# If DWARF combine fails, fall back to a stripped build
set +e
go build -o bin/app ./...
rc=$?
set -e
if [ $rc -ne 0 ]; then
  echo 'DWARF combine failed; building stripped' >&2
  go build -ldflags='-s -w' -o bin/app ./...
fi

Prevention

When it happens

Trigger: The program was compiled without debug info (`-ldflags='-s -w'` or `-gcflags=-l` stripping) yet the combine-DWARF path was triggered; `dsymutil` ran on a pre-stripped binary; the DWARF file passed in is actually a different kind of Mach-O (e.g. the executable itself, by mistake).

Common situations: Build pipeline stripping debug info before/instead of `dsymutil`; misconfigured CI passing the wrong file to the combine step; building with `-trimpath` plus aggressive strip flags.

Related errors


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