ipfs/kubo · warning

error reading log message: %s

Error message

error reading log message: %s

What it means

The log-streaming HTTP endpoint tails the daemon log through a pipe: a goroutine reads lines with bufio.Reader.ReadString and writes them to the HTTP response. If the read fails (pipe closed, daemon-side writer gone, EOF), the reader pushes 'error reading log message: <err>' onto an internal channel and stops streaming.

Source

Thrown at core/corehttp/logs.go:44

				case <-r.Context().Done(): // Client canceled request
				case <-n.Context().Done(): // Node shutdown
				case <-done: // log reader goroutine exitex
				}
				pipeReader.Close()
			}()

			errs := make(chan error, 1)

			go func() {
				defer close(errs)
				defer close(done)

				rdr := bufio.NewReader(pipeReader)
				for {
					// Read a line of log data and send it to the client.
					line, err := rdr.ReadString('\n')
					if err != nil {
						errs <- fmt.Errorf("error reading log message: %s", err)
						return
					}
					_, err = w.Write([]byte(line))
					if err != nil {
						// Failed to write to client, probably disconnected.
						return
					}
					if f, ok := w.(http.Flusher); ok {
						f.Flush()
					}
					if r.Context().Err() != nil {
						return
					}
				}
			}()
			log.Info("log API client connected")
			err := <-errs
			if err != nil {

View on GitHub (pinned to 329838acdf)

Solutions

  1. Reconnect the log stream client (e.g. rerun `ipfs log tail`); the error usually means the stream ended, most often due to daemon shutdown.
  2. Check whether the daemon is still running (`ipfs id`); restart it if it exited during the stream.
  3. Inspect daemon logs via the on-disk log file instead of the streaming endpoint to see what happened around the failure.
  4. If streaming repeatedly fails, report/inspect the pipe setup — a persistent read error indicates an I/O problem rather than a normal disconnect.

Example fix

// before: client keeps a fragile long-lived stream
ipfs log tail  # dies with daemon

// after: tolerate stream end and reconnect with backoff
for {
  ipfs log tail || true
  sleep 2
}
Defensive patterns

Strategy: retry

Validate before calling

// confirm the daemon is alive before (re)attaching a log stream
if err := shell.NewLocalShell().ID(); err != nil {
    return fmt.Errorf("daemon not reachable, not a stream problem: %w", err)
}

Try / catch

// client loop around the log stream
for {
    err := tailLogs(ctx) // POST /api/v0/log/tail and stream
    if ctx.Err() != nil { return ctx.Err() }
    log.Printf("log stream ended: %v; reconnecting in 2s", err)
    time.Sleep(2 * time.Second)
}

Prevention

When it happens

Trigger: While consuming the live log endpoint (used by `ipfs log tail`-style clients), the reading goroutine hits an error from rdr.ReadString('\n') — e.g. the log pipe writer was closed during daemon shutdown, or an I/O error on the pipe.

Common situations: Daemon shutting down while a client is tailing logs; log pipe closed unexpectedly; long-lived log streams dropped when the daemon restarts; embedded usages where the log writer is torn down independently of the HTTP handler.

Related errors


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