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
- Rebuild with `go build -a` to regenerate all host objects.
- Verify the named file exists and is readable: `ls -l <path>` and `file <path>`.
- If the path is relative, run `go build` from the module root so relative cgo paths resolve.
- 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
- Do not delete `_cgo_*` files or run `go clean -cache` mid-build.
- Run `go build` from the module root so relative cgo paths resolve.
- When redistributing a build, include all C objects, not just Go sources.
- Keep host-object paths absolute or module-relative.
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
- flag %q triggers external linking
- read namesize failed: %v
- read descsize failed: %v
- read type failed: %v
- read name failed: %v
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/24793903da21640c.
Report an issue: GitHub.