golang/go · error

%s: failed to open host object: %v

Error message

%s: failed to open host object: %v

What it means

When linking against host objects (C archives/objects from cgo), the linker opens each host object file by path to inspect its Mach-O load commands (e.g. to determine the deployment target via `hostobjMachoPlatform`). If `os.Open` fails — file missing, permission denied, path too long — the link fails with this message, naming the offending file and the OS error.

Source

Thrown at src/cmd/link/internal/ld/macho.go:1313

	}
	for i := 0; i < len(Segdwarf.Sections); i++ {
		sect := Segdwarf.Sections[i]
		si := dwarfp[i]
		if si.secSym() != sect.Sym ||
			ctxt.loader.SymSect(si.secSym()) != sect {
			panic("inconsistency between dwarfp and Segdwarf")
		}
		relocSect(ctxt, sect, si.syms)
	}
	wg.Wait()
}

// hostobjMachoPlatform returns the first platform load command found
// in the host object, if any.
func hostobjMachoPlatform(h *Hostobj) (*MachoPlatformLoad, error) {
	f, err := os.Open(h.file)
	if err != nil {
		return nil, fmt.Errorf("%s: failed to open host object: %v\n", h.file, err)
	}
	defer f.Close()
	sr := io.NewSectionReader(f, h.off, h.length)
	m, err := macho.NewFile(sr)
	if err != nil {
		// Not a valid Mach-O file.
		return nil, nil
	}
	return peekMachoPlatform(m)
}

// peekMachoPlatform returns the first LC_VERSION_MIN_* or LC_BUILD_VERSION
// load command found in the Mach-O file, if any.
func peekMachoPlatform(m *macho.File) (*MachoPlatformLoad, error) {
	for _, cmd := range m.Loads {
		raw := cmd.Raw()
		ml := MachoLoad{
			type_: m.ByteOrder.Uint32(raw),

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Rebuild with `go build -a` to regenerate all host objects.
  2. Verify the named file exists and is readable: `ls -l <path>` and `file <path>`.
  3. If the path is relative, run `go build` from the module root so relative cgo paths resolve.
  4. Reinstall the C dependency or re-run `go mod download` to restore missing artifacts.

Example fix

# before: stale cache references deleted host object
go build ./...

# after
go clean -cache && go build -a ./...
Defensive patterns

Strategy: validation

Validate before calling

# Ensure all cgo host objects exist and are readable before linking
for obj in $(go list -export -f '{{.ImportPath}}' ./... 2>/dev/null); do :; done
# Or simply verify the build cache is intact:
go env GOCACHE && test -d "$(go env GOCACHE)" && echo 'cache present'

Try / catch

set +e
go build ./...
rc=$?
set -e
if [ $rc -ne 0 ]; then
  echo 'link failed; rebuilding all host objects'
  go clean -cache && go build -a ./...
fi

Prevention

When it happens

Trigger: A cgo build where a recorded host-object path no longer exists (deleted, moved, or never installed); the object file is present but unreadable due to permissions; a relative path that resolves incorrectly because the build ran from a different working directory; a stale build cache referencing a removed file.

Common situations: Running `go clean -cache` mid-build (or `rm` on `_cgo_*` files); building on one machine and copying the cache to another without the C objects; container builds where a bind-mounted dependency was removed; cgo package whose `.a` was built outside the module cache and not redistributed.

Related errors


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