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

  1. Confirm the input is a complete darwin executable produced by the Go linker.
  2. Rebuild the binary: `go build` for GOOS=darwin.
  3. Re-download if the file was transferred incompletely.
  4. 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

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


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