{"record":{"id":"143e71455ad692a3","repo":"ipfs/kubo","slug":"stream-flush-failed-s","errorCode":null,"errorMessage":"stream flush failed: %s","messagePattern":"stream flush failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/commands/dag/export.go","lineNumber":87,"sourceCode":"\t}\n\tc := b.Path().RootCid()\n\n\tvar bs blockstore.Blockstore\n\tif localOnly {\n\t\tnode, err := cmdenv.GetNode(env)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbs = node.Blockstore\n\t}\n\n\tpipeR, pipeW := io.Pipe()\n\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 {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/dag/export.go#L69-L105","documentation":"This wraps the error returned when closing the write end of the `io.Pipe` that streams CAR bytes to the CLI output. In the `io.Pipe` model, `CloseWithError` causes the reader to receive the error; a plain `Close()` returning a non-nil error means the reader side had already failed (e.g. the consumer's `Emit` errored or stdout broke), so the write side reports the flush failure through `errCh`. It is reported only if no earlier error was already queued (buffered channel of size 2, first error wins).","triggerScenarios":"The traversal goroutine writes blocks to `pipeW` while the reading side has stopped or errored: consumer terminated the command (SIGINT/piped to `head`), the HTTP/CLI transport dropped, or `re.Emit` on the reader side failed, making the subsequent `pipeW.Close()` return the broken-pipe/write error.","commonSituations":"Piping `ipfs dag export` output into a consumer that exits early (e.g. `| head -c 100`); network interruption while the CAR writer goroutine is still mid-stream; disk/terminal write failures on the receiving end.","solutions":["Check the first error surfaced by the command, which is usually the underlying cause (e.g. broken pipe) rather than this wrapper.","Re-run the export and ensure the consumer reads the full stream or closes cleanly.","If the reader side is your code (RPC multipart consumer), fix why `Emit`/read aborted mid-stream."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := cmd.Run()\nvar opErr *net.OpError\nif errors.As(err, &opErr) && errors.Is(opErr.Err, syscall.EPIPE) {\n    // consumer closed the stream early; treat as non-fatal\n}","preventionTips":["Ensure the consumer reads the entire CAR stream or closes it cleanly.","Avoid piping export output into commands that exit early (e.g. head) without handling SIGPIPE.","Keep the connection to the daemon stable during long exports."],"tags":["io-pipe","broken-pipe","streaming"],"backgroundTag":"broken-pipe","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"}