ipfs/kubo · warning

stream flush failed: %s

Error message

stream flush failed: %s

What it means

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).

Source

Thrown at core/commands/dag/export.go:87

	}
	c := b.Path().RootCid()

	var bs blockstore.Blockstore
	if localOnly {
		node, err := cmdenv.GetNode(env)
		if err != nil {
			return err
		}
		bs = node.Blockstore
	}

	pipeR, pipeW := io.Pipe()

	errCh := make(chan error, 2) // we only report the 1st error
	go func() {
		defer func() {
			if err := pipeW.Close(); err != nil {
				errCh <- fmt.Errorf("stream flush failed: %s", err)
			}
			close(errCh)
		}()

		// Traversal decodes blocks with whatever codec their CID names, so it
		// runs third-party code. This goroutine is detached from the request,
		// and a panic on it would end the daemon rather than the command.
		// Registered after the close above so it runs first, while errCh is
		// still open.
		defer func() {
			if rec := recover(); rec != nil {
				log.Errorf("recovered from panic exporting %s: %v\n%s", c, rec, debug.Stack())
				errCh <- errors.New("internal error during CAR export")
			}
		}()

		if localOnly {
			if err := exportPartialCAR(req.Context, bs, c, pipeW); err != nil {

View on GitHub (pinned to 329838acdf)

Solutions

  1. Check the first error surfaced by the command, which is usually the underlying cause (e.g. broken pipe) rather than this wrapper.
  2. Re-run the export and ensure the consumer reads the full stream or closes cleanly.
  3. If the reader side is your code (RPC multipart consumer), fix why `Emit`/read aborted mid-stream.
Defensive patterns

Strategy: try-catch

Try / catch

err := cmd.Run()
var opErr *net.OpError
if errors.As(err, &opErr) && errors.Is(opErr.Err, syscall.EPIPE) {
    // consumer closed the stream early; treat as non-fatal
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/143e71455ad692a3. Report an issue: GitHub.