{"record":{"id":"92b44e6eab2467e5","repo":"golang/go","slug":"fail-to-seek","errorCode":null,"errorMessage":"fail to seek","messagePattern":"fail to seek","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/link/internal/loadpe/ldpe.go","lineNumber":159,"sourceCode":"\t// that loads from the corresponding import symbol and then does\n\t// a jump to the loaded value.\n\tCreateImportStubPltToken = -2\n\n\t// When stored into the GOT value for an import symbol __imp_X this\n\t// token tells windynrelocsym to redirect references to the\n\t// underlying DYNIMPORT symbol X.\n\tRedirectToDynImportGotToken = -2\n)\n\n// TODO(brainman): maybe just add ReadAt method to bio.Reader instead of creating peBiobuf\n\n// peBiobuf makes bio.Reader look like io.ReaderAt.\ntype peBiobuf bio.Reader\n\nfunc (f *peBiobuf) ReadAt(p []byte, off int64) (int, error) {\n\tret := ((*bio.Reader)(f)).MustSeek(off, 0)\n\tif ret < 0 {\n\t\treturn 0, errors.New(\"fail to seek\")\n\t}\n\tn, err := f.Read(p)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn n, nil\n}\n\n// makeUpdater creates a loader.SymbolBuilder if one hasn't been created previously.\n// We use this to lazily make SymbolBuilders as we don't always need a builder, and creating them for all symbols might be an error.\nfunc makeUpdater(l *loader.Loader, bld *loader.SymbolBuilder, s loader.Sym) *loader.SymbolBuilder {\n\tif bld != nil {\n\t\treturn bld\n\t}\n\tbld = l.MakeSymbolUpdater(s)\n\treturn bld\n}\n","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/link/internal/loadpe/ldpe.go#L141-L177","documentation":"Returned by peBiobuf.ReadAt when the underlying bio.Reader.MustSeek returns a negative value, indicating the seek to the requested offset failed. peBiobuf adapts a buffered I/O reader to the io.ReaderAt interface so PE section readers (which use ReadAt) can random-access the linker's input. A failed seek means the requested offset is unreachable on the stream backing the PE file.","triggerScenarios":"The PE loader (loadpe) calls ReadAt on a section offset that lies outside the buffered reader's valid range — typically because the file is truncated, the PE section header claims a larger offset/size than the file provides, or the reader's position was corrupted. MustSeek(off,0) < 0 triggers the error.","commonSituations":"Linking against a truncated or partially-written Windows .obj/.dll, a corrupt PE produced by a crashed build, or a PE with malformed section headers pointing past EOF. Often seen when cgo links a Windows resource or import library that was incompletely downloaded.","solutions":["Rebuild or re-fetch the offending PE input (object/import library/DLL) — truncation is the usual cause.","Verify the file integrity with `go tool nm` or a PE inspector (dumpbin/objdump) before linking.","If the file is valid, ensure the linker is reading the same file (check -I/-L paths and build cache for stale copies).","Check for disk-full or interrupted-write artifacts in the build cache; `go clean -cache` and rebuild."],"exampleFix":"// before: linking a truncated .dll\ngo build -o app.exe\n// ldpe: fail to seek\n\n// after: re-fetch and rebuild\ngo clean -cache\n# ensure the import library is complete, then:\ngo build -o app.exe","handlingStrategy":"validation","validationCode":"// Verify the PE input is complete and its sections are within EOF before linking.\nfunc peSectionsWithinEOF(path string) error {\n    f, err := os.Open(path)\n    if err != nil { return err }\n    defer f.Close()\n    fi, _ := f.Stat()\n    pf, err := pe.NewFile(f)\n    if err != nil { return err }\n    for _, s := range pf.Sections {\n        if int64(s.Offset)+int64(s.Size) > fi.Size() {\n            return fmt.Errorf(\"section %s extends past EOF\", s.Name)\n        }\n    }\n    return nil\n}","typeGuard":"func isSeekFail(err error) bool {\n    return err != nil && err.Error() == \"fail to seek\"\n}","tryCatchPattern":"if err := loadpe.Load(...); err != nil && err.Error() == \"fail to seek\" {\n    return fmt.Errorf(\"PE input %s appears truncated: %w\", pn, err)\n}","preventionTips":["Validate PE section headers fit within the file size before linking.","Re-fetch and rebuild truncated import libraries or objects.","Clean the build cache after interrupted builds."],"tags":["pe","windows","linker","binary-parsing","seek"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}