golang/go · error
failed to open shared library: %v
Error message
failed to open shared library: %v
What it means
readpkglist calls elf.Open on a gccgo-built shared library path to extract its embedded package list. If elf.Open returns an error (file missing, not ELF, truncated), the go command calls base.Fatal with this wrapped error, terminating the build.
Source
Thrown at src/cmd/go/internal/work/action.go:404
//
// NewObjdir must be called only from a single goroutine at a time,
// so it is safe to call during action graph construction, but it must not
// be called during action graph execution.
func (b *Builder) NewObjdir() string {
b.objdirSeq++
return str.WithFilePathSeparator(filepath.Join(b.WorkDir, fmt.Sprintf("b%03d", b.objdirSeq)))
}
// readpkglist returns the list of packages that were built into the shared library
// at shlibpath. For the native toolchain this list is stored, newline separated, in
// an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
// .go_export section.
func readpkglist(s *modload.Loader, shlibpath string) (pkgs []*load.Package) {
var stk load.ImportStack
if cfg.BuildToolchainName == "gccgo" {
f, err := elf.Open(shlibpath)
if err != nil {
base.Fatal(fmt.Errorf("failed to open shared library: %v", err))
}
defer f.Close()
sect := f.Section(".go_export")
if sect == nil {
base.Fatal(fmt.Errorf("%s: missing .go_export section", shlibpath))
}
data, err := sect.Data()
if err != nil {
base.Fatal(fmt.Errorf("%s: failed to read .go_export section: %v", shlibpath, err))
}
pkgpath := []byte("pkgpath ")
for _, line := range bytes.Split(data, []byte{'\n'}) {
if path, found := bytes.CutPrefix(line, pkgpath); found {
path = bytes.TrimSuffix(path, []byte{';'})
pkgs = append(pkgs, load.LoadPackageWithFlags(s, string(path), base.Cwd(), &stk, nil, 0))
}
}
} else {View on GitHub (pinned to b6b368adc5)
Solutions
- Run 'go clean -cache' to discard stale shared-library references.
- Rebuild the shared library with -buildmode=shared so its path is fresh.
- Verify the shlibpath exists and is readable: 'file <path>' should report ELF.
- Ensure GOFLAGS/-pkgdir isn't pointing at a stale output tree.
Example fix
// before: stale cache references a deleted .so $ go build -buildmode=shared -linkshared ./... // error: failed to open shared library: open /tmp/.../libstd.so: no such file // after $ go clean -cache $ go build -buildmode=shared -o libstd.so std $ go build -linkshared ./...
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify a gccgo shared library is a readable ELF before referencing it.
func checkShlib(path string) error {
f, err := elf.Open(path)
if err != nil { return fmt.Errorf("%s: not a readable ELF", path) }
defer f.Close()
return nil
} Try / catch
// Treat a missing/corrupt shlib as a cache reset, not a fatal error.
if _, err := readpkglist(loader, path); err != nil {
log.Printf("shlib unreadable, resetting cache: %v", err)
_ = os.RemoveAll(cfg.GOCACHE)
// rebuild shared libs and retry
} Prevention
- Run 'go clean -cache' when switching between -buildmode=shared runs.
- Keep GOCACHE on a stable local filesystem.
- Don't manually delete .so files out from under the build cache.
When it happens
Trigger: Building with -buildmode=shared under gccgo, or consuming a prior -shared gccgo artifact, where the recorded shlib path is unreadable, deleted, or not an ELF file. Also triggered by a stale build cache pointing at a removed .so.
Common situations: Build cache corruption; the .so was garbage-collected (GOCACHE cleanup) but its cache entry remained; cross-mounted filesystem where the .so isn't visible; a non-gccgo .so being interpreted as one.
Related errors
- %s: missing .go_export section
- %s: failed to read .go_export section: %v
- too long
- file is empty
- entry file incomplete
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/ab538852539fc5eb.
Report an issue: GitHub.