How do you modify HTTP response headers on feed/?

If you just want to change the Content-Type header, then the feed_content_type filter can indeed be used for that purpose. (If your code isn’t changing the header, then another code might have overridden that header, so you can try using a lower priority for your filter callback)

But there’s another filter hook you can use, namely wp_headers. You can use it to change/remove the response headers set by WordPress on any pages.

So for example, for feed requests (/feed, /feed/atom, /comments/feed, etc.), WordPress sets the Content-Type, Last-Modified and ETag headers, hence you can change/remove any of that headers using the wp_headers filter.

However, as for what you’re trying to do — display a WordPress’s 404 page when the request is for a feed, a simpler way to do that is by using the parse_request action hook to change the request to a non-feed request and then set the error query var to 404 which then automatically intructs WordPress to show a 404 error page.

Working Example

add_action( 'parse_request', 'my_disable_feed_request' );
function my_disable_feed_request( $wp ) {
    // If it's a feed request, empty the `feed` query var and then make
    // WordPress shows a 404 error page by setting the `error` to 404.
    if ( ! empty( $wp->query_vars['feed'] ) ) {
        $wp->query_vars['feed']  = '';
        $wp->query_vars['error'] = '404';

So with that, you don’t need to use the code in question, and actually, those do_feed hooks would no longer run because the feed request has been intercepted.

Note though, the above code will apply to any core WordPress feed URLs, so if you want the code to apply to the main feeds only, you can check if the request path starts with feed/ or that it’s exactly feed, like so:

if ( ! empty( $wp->query_vars['feed'] ) && preg_match( '#^feed(/|$)#', $wp->request ) )