{"record":{"id":"5a2a566583334b32","repo":"go-delve/delve","slug":"can-t-open-separate-debug-file","errorCode":null,"errorMessage":"can't open separate debug file: ","messagePattern":"can't open separate debug file: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/bininfo.go","lineNumber":1687,"sourceCode":"\t\t\tnotify = func(s string) {\n\t\t\t\tbi.eventsFn(&Event{\n\t\t\t\t\tKind: EventBinaryInfoDownload,\n\t\t\t\t\tBinaryInfoDownloadEventDetails: &BinaryInfoDownloadEventDetails{\n\t\t\t\t\t\tImagePath: image.Path,\n\t\t\t\t\t\tProgress:  s,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tdebugFilePath, err = debuginfod.GetDebuginfo(bi.downloadsCtx, notify, image.BuildID)\n\t\tif err != nil {\n\t\t\treturn nil, nil, ErrNoDebugInfoFound\n\t\t}\n\t}\n\n\tsepFile, err := os.OpenFile(debugFilePath, 0, os.ModePerm)\n\tif err != nil {\n\t\treturn nil, nil, errors.New(\"can't open separate debug file: \" + err.Error())\n\t}\n\n\telfFile, err := elf.NewFile(sepFile)\n\tif err != nil {\n\t\tsepFile.Close()\n\t\treturn nil, nil, fmt.Errorf(\"can't open separate debug file %q: %v\", debugFilePath, err.Error())\n\t}\n\n\tif !supportedLinuxArch[elfFile.Machine] {\n\t\tsepFile.Close()\n\t\treturn nil, nil, fmt.Errorf(\"can't open separate debug file %q: %v\", debugFilePath, &ErrUnsupportedArch{os: \"linux\", cpuArch: elfFile.Machine})\n\t}\n\n\treturn sepFile, elfFile, nil\n}\n\n// loadBinaryInfoElf specifically loads information from an ELF binary.\nfunc loadBinaryInfoElf(bi *BinaryInfo, image *Image, path string, addr uint64, wg *sync.WaitGroup) error {","sourceCodeStart":1669,"sourceCodeEnd":1705,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/bininfo.go#L1669-L1705","documentation":"When the executable itself lacks debug info, Delve follows the GNU debuglink/build-id to a separate debug file and tries to open it with os.OpenFile. If that open fails (the path exists per debuglink but is unreadable/absent), it returns 'can't open separate debug file: <reason>'. The message deliberately embeds the OS error.","triggerScenarios":"debuglink points to a file path that doesn't exist or has bad permissions; os.OpenFile(debugFilePath, 0, os.ModePerm) fails with ENOENT/EACCES during loadBinaryInfoElf's separate-debug-file resolution.","commonSituations":"Debug packages not installed on the machine; /usr/lib/debug trees missing after container image slimming; wrong permissions on the .debug file; stale debuglink after the binary was copied to another host.","solutions":["Install the matching debug symbols package so the debuglink/build-id target exists","Check permissions on the debug file path shown in the wrapped OS error (chmod a+r)","Verify the debuglink path: the file must be at <dir>/<link>, <dir>/.debug/<link>, or /usr/lib/debug/<dir>/<link>","Copy the unstripped binary or .debug file from the build machine to the same relative path"],"exampleFix":"// before\n$ ls /usr/lib/debug/usr/bin/app\nls: cannot access ... No such file or directory\n// after\n$ apt-get install app-dbg   # or copy app.debug next to the binary\n$ chmod a+r /usr/lib/debug/usr/bin/app","handlingStrategy":"validation","validationCode":"func debugFileResolves(binaryPath, debugLink string) error {\n    for _, p := range []string{\n        filepath.Join(filepath.Dir(binaryPath), debugLink),\n        filepath.Join(filepath.Dir(binaryPath), \".debug\", debugLink),\n        filepath.Join(\"/usr/lib/debug\", filepath.Dir(binaryPath), debugLink)} {\n        if _, err := os.Stat(p); err == nil { return nil }\n    }\n    return fmt.Errorf(\"debug file %s not found for %s\", debugLink, binaryPath)\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := loadSeparateDebugFile(...); err != nil {\n    if strings.HasPrefix(err.Error(), \"can't open separate debug file:\") {\n        // check wrapped OS error: ENOENT -> install dbgsym; EACCES -> fix permissions\n    }\n}","preventionTips":["Install matching debug symbol packages on the machine doing the debugging","Ensure .debug files are world-readable after copying","Keep the stripped binary and its .debug file at consistent relative paths across hosts"],"tags":["debug-info","separate-debug-file","elf","file-access"],"backgroundTag":"separate-debug-file-open-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}