{"record":{"id":"1e704113bb60c119","repo":"ipfs/kubo","slug":"copying-binary-q-w","errorCode":null,"errorMessage":"copying binary %q: %w","messagePattern":"copying binary %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"profile/profile.go","lineNumber":242,"sourceCode":"\t\terr  error\n\t)\n\tif goos == \"linux\" {\n\t\tpid := os.Getpid()\n\t\tpath = fmt.Sprintf(\"/proc/%d/exe\", pid)\n\t} else {\n\t\tpath, err = os.Executable()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"finding binary path: %w\", err)\n\t\t}\n\t}\n\tfi, err := os.Open(path)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"opening binary %q: %w\", path, err)\n\t}\n\t_, err = io.Copy(w, fi)\n\t_ = fi.Close()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"copying binary %q: %w\", path, err)\n\t}\n\treturn nil\n}\n\nfunc mutexProfile(ctx context.Context, opts Options, w io.Writer) error {\n\tprev := runtime.SetMutexProfileFraction(opts.MutexProfileFraction)\n\tdefer runtime.SetMutexProfileFraction(prev)\n\terr := waitOrCancel(ctx, opts.ProfileDuration)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn pprof.Lookup(\"mutex\").WriteTo(w, 2)\n}\n\nfunc blockProfile(ctx context.Context, opts Options, w io.Writer) error {\n\truntime.SetBlockProfileRate(int(opts.BlockProfileRate.Nanoseconds()))\n\tdefer runtime.SetBlockProfileRate(0)\n\terr := waitOrCancel(ctx, opts.ProfileDuration)","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/profile/profile.go#L224-L260","documentation":"binary() copies the executable bytes into the profile archive with io.Copy(w, fi), closes the file, and wraps any copy error as \"copying binary %q\" with the path. Collection already succeeded in finding and opening the binary; the failure happened while streaming its bytes into the destination writer.","triggerScenarios":"io.Copy(w, fi) fails: the destination writer w (the profile buffer feeding the archive) hit an underlying write error, the binary file shrank/vanished mid-read (upgrade race), read() returned EIO on a damaged filesystem, or large binaries hit a size limit on the output.","commonSituations":"Disk filling up while a multi-hundred-MB binary is being embedded; concurrent self-upgrade truncating the executable during read; reading from a flaky network/overlay filesystem inside containers.","solutions":["Read the wrapped path and inner error to find whether read or write side failed","Check disk space on the archive destination before embedding large binaries","Never mutate/delete the running binary while profiling (serialize upgrade and profile collection)","Consider excluding the binary collector for very large executables if archives are size-constrained"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if st, err := os.Stat(binPath); err != nil || st.Size() > maxEmbedSize {\n    return skipBinaryCollector\n}","typeGuard":null,"tryCatchPattern":"if err := WriteProfiles(ctx, p); err != nil {\n    if strings.HasPrefix(err.Error(), \"copying binary\") {\n        log.Printf(\"binary copy failed mid-stream (%v); retry without concurrent upgrade\", errors.Unwrap(err))\n    }\n    return err\n}","preventionTips":["Serialize binary upgrades and profile collection so the image never changes mid-read","Ensure enough free space for an archive that includes the full executable","Check filesystem health if EIO appears during reads","Skip binary embedding for very large executables or size-limited archives"],"tags":["io","diagnostics","filesystem","concurrency"],"backgroundTag":"file-read-io-failed","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}