(For same-origin requests, CORS doesn't come into play.)
I'm not able to reproduce the problem you describe; here's a live deployment of a site with a service worker that makes a request to the https://httpbin.org/#/Request_inspection/get_headers endpoint when it starts up, and logs the response back, indicating what request headers were received:
fetch('https://httpbin.org/headers', {
headers: {'my-custom-header': 'a value'},
})
.then((response) => response.json())
.then((data) => console.log(data.headers));
In Chrome, Firefox, and Safari, I see the custom header returned along with the other headers that are sent by default by the browser.
You can play around with this and test out different scenarios by remixing https://glitch.com/edit/#!/valuable-nonchalant-pet?path=sw.js%3A3%3A81