close_notify has always used a warning alert level, but this is not actually written down anywhere. It seems to have gotten lost as early as RFC 4346 (TLS 1.1!). In RFC 2246, there is some text that mentions the correct level is warning as an aside in describing something else.
close_notify
This message notifies the recipient that the sender will not send
any more messages on this connection. The session becomes
unresumable if any connection is terminated without proper
close_notify messages with level equal to warning.
I wasn't able to find any other text that discussed this. Then, RFC 4346 dropped the session termination behavior:
close_notify
This message notifies the recipient that the sender will not send
any more messages on this connection. Note that as of TLS 1.1,
failure to properly close a connection no longer requires that a
session not be resumed. This is a change from TLS 1.0 to conform
with widespread implementation practice.
But in doing so, it dropped any mention of which alert level to use. That text has carried over to RFC 8446 as:
close_notify: This alert notifies the recipient that the sender will
not send any more messages on this connection. Any data received
after a closure alert has been received MUST be ignored.
In RFC 8446, we said alert levels no longer matter and can be "safely ignored", but this still leaves unspecified what the sender should do. Skimming implementations, both BoringSSL and NSS will treat "fatal" close_notify as an error, so using "warning" is also necessary for interop.
close_notify has always used a warning alert level, but this is not actually written down anywhere. It seems to have gotten lost as early as RFC 4346 (TLS 1.1!). In RFC 2246, there is some text that mentions the correct level is warning as an aside in describing something else.
I wasn't able to find any other text that discussed this. Then, RFC 4346 dropped the session termination behavior:
But in doing so, it dropped any mention of which alert level to use. That text has carried over to RFC 8446 as:
In RFC 8446, we said alert levels no longer matter and can be "safely ignored", but this still leaves unspecified what the sender should do. Skimming implementations, both BoringSSL and NSS will treat "fatal" close_notify as an error, so using "warning" is also necessary for interop.