Why does net/http client print internal errors with log.Printf?

When using the Go standard library net/http client, I sometimes see messages like:

Unsolicited response received on idle HTTP channel starting with ...

This output is not coming from my code. It seems to be printed directly by the Go standard library using log.Printf.

I thought the Go philosophy was that libraries should not print logs directly, but instead return errors. Why is net/http an exception here?

I agree this is odd. This specific bit of code seems to be adapted from some very old Go code. I git blamed that bit and found it was modified in 2019:

https://go-review.googlesource.com/c/go/+/181239

BUT - the decision to log.Printf has been there for a very long time. For example, it was here when they moved those files around:

You could trace it earlier than that to try to find rationale, but, it seems like they originally thought “this won’t happen often and is like a warning”. And then that legacy bit was never revisited.

Hello, it prints errors into the setup-ed ErrorLog when you are creating a server.

// ErrorLog specifies an optional logger for errors accepting
// connections, unexpected behavior from handlers, and
// underlying FileSystem errors.
// If nil, logging is done via the log package's standard logger.
ErrorLog *log.Logger

Edit: my bad, it’s http.Transport you are talking about, not server