The issue here is that you aren't providing an HTTPS-only site. An HTTPS-only site would literally not respond on port 80 at all.
When someone accesses your site using HTTP, if you send a 301 and then use HSTS, that browser will literally never connect over HTTP again unless you clear the HSTS cache. This is still subject to an attack on the initial connection, but the exposure of the data is one time per user, which is the best that you can do (unless you preload your site in browsers).
When you send a 404, the user may try to use your site over HTTP again. If they were following an HTTP link to your site, that data will be exposed, and it will be every time they do so, even if all you serve them is a 404.
Note that the exposure of the data here need not be restricted to data you serve to the user. Which pages the user requests and visits are sensitive and should always be encrypted. Additionally, HTTP accesses can be intercepted by bad actors and injected with data or otherwise modified; Southwest Airlines does this on its flights to inject a header, and Verizon injects an advertising ID. Serving a 404 just confuses the user and solves only a fraction of the problems that occur with serving data over HTTP.
The goal of HSTS is to tell the browser that your site should always be accessed over HTTPS. The goal of the 301 is to get your users to see a valid Strict-Transport-Security
header (which must be served over HTTPS) as soon as possible. Together, those minimize the risk of attacks on plaintext connections.
You could literally not serve any HTTP service (port 80) at all, which would be acceptable. However, browsers still tend to default to HTTP, so this may result in users being confused as to why your site is “broken” if they don't type the protocol.