golang/go · error · fs.PathError
cannot find __text section
Error message
cannot find __text section
What it means
Returned by the Mach-O build-id reader when mf.Section("__text") returns nil. Every Mach-O executable has a __text section containing executable instructions; its absence means the file is not a well-formed Mach-O binary or is missing the text segment, so the Go build ID (embedded near the start of __text) cannot be located.
Source
Thrown at src/cmd/internal/buildid/note.go:196
// Sadly, that's not guaranteed to hold the note, because there is an arbitrary amount
// of other junk placed in the file ahead of the main text.
func readMacho(name string, f *os.File, data []byte) (buildid string, err error) {
// If the data we want has already been read, don't worry about Mach-O parsing.
// This is both an optimization and a hedge against the Mach-O parsing failing
// in the future due to, for example, the name of the __text section changing.
if b, err := readRaw(name, data); b != "" && err == nil {
return b, err
}
mf, err := macho.NewFile(f)
if err != nil {
return "", &fs.PathError{Path: name, Op: "parse", Err: err}
}
sect := mf.Section("__text")
if sect == nil {
// Every binary has a __text section. Something is wrong.
return "", &fs.PathError{Path: name, Op: "parse", Err: fmt.Errorf("cannot find __text section")}
}
// It should be in the first few bytes, but read a lot just in case,
// especially given our past problems on OS X with the build ID moving.
// There shouldn't be much difference between reading 4kB and 32kB:
// the hard part is getting to the data, not transferring it.
n := sect.Size
if n > uint64(readSize) {
n = uint64(readSize)
}
buf := make([]byte, n)
if _, err := f.ReadAt(buf, int64(sect.Offset)); err != nil {
return "", err
}
return readRaw(name, buf)
}
View on GitHub (pinned to b6b368adc5)
Solutions
- Confirm the input is a complete darwin executable produced by the Go linker.
- Rebuild the binary: `go build` for GOOS=darwin.
- Re-download if the file was transferred incompletely.
- Check the file with `file <bin>` and `otool -L <bin>` to validate Mach-O structure.
Defensive patterns
Strategy: validation
Validate before calling
// before reading a Mach-O build id, confirm it is an executable with __text:
mf, err := macho.Open(bin)
if err != nil { return err }
if mf.Section("__text") == nil {
return errors.New("not a Mach-O executable (no __text)")
} Prevention
- Pass Mach-O executables (.dylib/exe), not .o object files, to build-id readers.
- Validate with `file <bin>` on darwin before processing.
- Re-download incomplete darwin artifacts.
When it happens
Trigger: Calling the Mach-O path of buildid (triggered for darwin/amd64 and darwin/arm64 binaries) on a file that macho.NewFile parsed but which lacks a __text section — e.g. a Mach-O object file, a relocatable bundle, a stub, or a corrupt executable.
Common situations: Pointing the toolchain at a Mach-O object (.o) rather than an executable, a binary stripped of its text segment, a corrupt download, or a non-Go Mach-O file that happens to enter this code path.
Related errors
- read namesize failed: %v
- read descsize failed: %v
- read type failed: %v
- read name failed: %v
- read desc failed: %v
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/3320a59b15c33f94.
Report an issue: GitHub.