golang/go · error
unexpected content after code signature
Error message
unexpected content after code signature
What it means
When the linker resizes a Mach-O code signature in place, it requires the signature to be the final bytes of the output file (Apple's codesign invariant: anything after the signature superblob invalidates it). The check `sigOff+sigSz != fi.Size()` detects trailing bytes — if present, the link aborts because patching the signature would leave an unverifiable binary.
Source
Thrown at src/cmd/link/internal/ld/macho.go:1569
}
}
loadOff += int64(sz)
}
if sigOff == 0 {
// The C linker doesn't generate a signed binary, for some reason.
// Skip.
return nil
}
fi, err := f.Stat()
if err != nil {
return err
}
if sigOff+sigSz != fi.Size() {
// We don't expect anything after the signature (this will invalidate
// the signature anyway.)
return fmt.Errorf("unexpected content after code signature")
}
sz := codesign.Size(sigOff, "a.out")
if sz != sigSz {
// Update the load command,
var tmp [8]byte
mf.ByteOrder.PutUint32(tmp[:4], uint32(sz))
_, err = f.WriteAt(tmp[:4], csCmdOff+12)
if err != nil {
return err
}
// Uodate the __LINKEDIT segment.
segSz := sigOff + sz - int64(linkeditSeg.Offset)
mf.ByteOrder.PutUint64(tmp[:8], uint64(segSz))
_, err = f.WriteAt(tmp[:8], linkeditOff+int64(unsafe.Offsetof(macho.Segment64{}.Memsz)))
if err != nil {
return errView on GitHub (pinned to b6b368adc5)
Solutions
- Ensure the Go linker runs before any external `codesign`/post-processing, not after.
- Delete the output binary and relink from scratch so the signature is the last thing written.
- Remove custom `-extldflags` that alter the output tail; use the default external linker behavior.
- Avoid concurrent builds writing to the same output path.
Example fix
# before: external codesign ran, then linker tried to resize sig codesign -s MySign bin/app # wrong order go build -o bin/app ./... # after: link first, sign last go build -o bin/app ./... codesign -s MySign bin/app
Defensive patterns
Strategy: validation
Validate before calling
# Before relinking, confirm the existing binary has no trailing bytes after the signature if [ -f bin/app ]; then codesign -dv bin/app 2>&1 | grep -q 'CodeDirectory v' && echo 'binary is signed; relink from scratch instead of patching' fi
Try / catch
# Relink cleanly on failure rather than patch a signed binary set +e go build -o bin/app ./... rc=$? set -e if [ $rc -ne 0 ]; then rm -f bin/app go build -o bin/app ./... fi
Prevention
- Always run the Go linker before `codesign`, never after.
- Relink from scratch rather than re-patching an existing signed binary.
- Do not run two linkers concurrently on the same output file.
- Avoid `-extldflags` that append trailing data to the Mach-O.
When it happens
Trigger: The combine-DWARF or codesign-update flow running on a binary already modified by an external tool (`codesign`, `dsymutil`, a custom post-linker) that appended data; a prior interrupted linker run that left partial trailing data; an external `-extld` that produced a non-standard tail layout.
Common situations: A build pipeline that runs `codesign` then re-invokes the Go linker; mixing `go build` with a post-processing step that pads the binary; concurrent/duplicate link invocations writing the same output file.
Related errors
- missing __LINKEDIT segment
- missing __text section
- no room to add dwarf info. Need at least %d padding bytes, f
- cannot find __go_fipsinfo
- invalid version %q
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/a485f05e81130eaf.
Report an issue: GitHub.