golang/go · error

fail to seek

Error message

fail to seek

What it means

Returned by xcoffBiobuf.ReadAt when the underlying bio.Reader.MustSeek returns a negative value. xcoffBiobuf adapts a buffered I/O reader to io.ReaderAt so XCOFF (AIX) section readers can random-access the linker's input. A failed seek means the requested offset is unreachable on the stream backing the XCOFF file.

Source

Thrown at src/cmd/link/internal/loadxcoff/ldxcoff.go:33

	"fmt"
	"internal/xcoff"
)

// ldSection is an XCOFF section with its symbols.
type ldSection struct {
	xcoff.Section
	sym loader.Sym
}

// TODO(brainman): maybe just add ReadAt method to bio.Reader instead of creating xcoffBiobuf

// xcoffBiobuf makes bio.Reader look like io.ReaderAt.
type xcoffBiobuf bio.Reader

func (f *xcoffBiobuf) ReadAt(p []byte, off int64) (int, error) {
	ret := ((*bio.Reader)(f)).MustSeek(off, 0)
	if ret < 0 {
		return 0, errors.New("fail to seek")
	}
	n, err := f.Read(p)
	if err != nil {
		return 0, err
	}
	return n, nil
}

// loads the Xcoff file pn from f.
// Symbols are written into loader, and a slice of the text symbols is returned.
func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (textp []loader.Sym, err error) {
	errorf := func(str string, args ...any) ([]loader.Sym, error) {
		return nil, fmt.Errorf("loadxcoff: %v: %v", pn, fmt.Sprintf(str, args...))
	}

	var ldSections []*ldSection

	f, err := xcoff.NewFile((*xcoffBiobuf)(input))

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Rebuild or re-fetch the offending XCOFF input; truncation is the usual cause.
  2. Inspect the file with an XCOFF tool (dump on AIX, or `go tool nm`) to confirm section offsets are within EOF.
  3. Clean the build cache (`go clean -cache`) and rebuild to discard stale partial objects.
  4. If the file is valid, verify the linker resolves the same path (check library search paths).

Example fix

// before: GOOS=aix build against a truncated .a
goos=aix go build
// ldxcoff: fail to seek

// after
go clean -cache
# ensure the XCOFF archive is complete, then rebuild
goos=aix go build
Defensive patterns

Strategy: validation

Validate before calling

// Verify the XCOFF input is complete and its sections are within EOF before linking.
func xcoffSectionsWithinEOF(path string) error {
    f, err := os.Open(path)
    if err != nil { return err }
    defer f.Close()
    fi, _ := f.Stat()
    xf, err := xcoff.NewFile(f)
    if err != nil { return err }
    for _, s := range xf.Sections {
        if int64(s.Offset)+int64(s.Size) > fi.Size() {
            return fmt.Errorf("section %s extends past EOF", s.Name)
        }
    }
    return nil
}

Type guard

func isSeekFail(err error) bool {
    return err != nil && err.Error() == "fail to seek"
}

Try / catch

if err := loadxcoff.Load(...); err != nil && err.Error() == "fail to seek" {
    return fmt.Errorf("XCOFF input %s appears truncated: %w", pn, err)
}

Prevention

When it happens

Trigger: The XCOFF loader (loadxcoff) calls ReadAt on a section/symbol offset outside the buffered reader's valid range — a truncated file, malformed XCOFF header pointing past EOF, or corrupted reader position. MustSeek(off,0) < 0 triggers the error.

Common situations: Cross-building for AIX (GOOS=aix) against a truncated or corrupt XCOFF object/archive; a build-cache artifact left by an interrupted write; an XCOFF import library downloaded incompletely.

Related errors


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