{"record":{"id":"e28bafbd59840223","repo":"ipfs/kubo","slug":"internal-error-during-car-export","errorCode":null,"errorMessage":"internal error during CAR export","messagePattern":"internal error during CAR export","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/commands/dag/export.go","lineNumber":100,"sourceCode":"\n\terrCh := make(chan error, 2) // we only report the 1st error\n\tgo func() {\n\t\tdefer func() {\n\t\t\tif err := pipeW.Close(); err != nil {\n\t\t\t\terrCh <- fmt.Errorf(\"stream flush failed: %s\", err)\n\t\t\t}\n\t\t\tclose(errCh)\n\t\t}()\n\n\t\t// Traversal decodes blocks with whatever codec their CID names, so it\n\t\t// runs third-party code. This goroutine is detached from the request,\n\t\t// and a panic on it would end the daemon rather than the command.\n\t\t// Registered after the close above so it runs first, while errCh is\n\t\t// still open.\n\t\tdefer func() {\n\t\t\tif rec := recover(); rec != nil {\n\t\t\t\tlog.Errorf(\"recovered from panic exporting %s: %v\\n%s\", c, rec, debug.Stack())\n\t\t\t\terrCh <- errors.New(\"internal error during CAR export\")\n\t\t\t}\n\t\t}()\n\n\t\tif localOnly {\n\t\t\tif err := exportPartialCAR(req.Context, bs, c, pipeW); err != nil {\n\t\t\t\terrCh <- err\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tlsys := cidlink.DefaultLinkSystem()\n\t\tlsys.SetReadStorage(&dagStore{dag: api.Dag(), ctx: req.Context})\n\n\t\t// Uncomment the following to support CARv2 output.\n\t\t/*\n\t\t\tcar, err := gocar.NewSelectiveWriter(req.Context, &lsys, c, selectorparse.CommonSelector_ExploreAllRecursively, gocar.AllowDuplicatePuts(false))\n\t\t\tif err != nil {\n\t\t\t\terrCh <- err","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/dag/export.go#L82-L118","documentation":"The CAR export traversal runs third-party codec decoding code, and a panic there would kill the whole daemon, so the goroutine registers a `recover()` handler. When a panic is caught, the original panic (with stack) is logged server-side and this generic sentinel error is sent to the caller instead. It intentionally hides internal details from the user while preserving the crash trace in the daemon log.","triggerScenarios":"The block traversal/codec code for the requested CID panics: typically malformed or corrupt block data whose decoder hits an unhandled edge case, or a bug in an IPLD codec invoked during `exportPartialCAR` or the full CAR export path.","commonSituations":"Exporting a DAG containing corrupt or adversarially crafted blocks; a codec implementation bug for an exotic IPLD codec; memory corruption triggered during traversal of a huge DAG.","solutions":["Search the daemon log for `recovered from panic exporting` to find the CID, panic value, and stack trace.","Verify the block data with `ipfs dag stat` / `ipfs block get` on the affected CID to identify the corrupt block.","Report the stack trace to kubo/boxo (github.com/ipfs/kubo/issues) since a panic in a codec is a bug.","Work around locally by removing/re-fetching the corrupt block (gc + re-download) if the source was bad."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"internal error during CAR export\") {\n    // inspect daemon log for \"recovered from panic exporting\" and the CID\n    // retry with a different node or after removing/re-fetching the corrupt block\n}","preventionTips":["Keep kubo and boxo updated to pick up codec panic fixes.","Validate DAG integrity (ipfs dag stat) before exporting untrusted content.","Monitor daemon logs for recovered panics to catch corrupt blocks early."],"tags":["panic","internal-error","car-export","ipld-codec"],"backgroundTag":"panic-recovered-internal-error","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"}