My suggestion: simplify your scenario to see what is really going on.
I just tried this in my Apigee X organization, and it works as expected.
I have a simple proxy with a CORS policy in the Preflow. And a conditional flow that calls VerifyAPIKey. That one does not always execute. The VerifyAPIKey is there, so that I can conditionally cause a fault.
The proxy has a DefaultFaultRule which injects a header into the response. The DFR will execute in the fault condition that occurs if the proxy executes the conditional flow that calls VerifyAPIKey, but there is no api key. I see the expected behavior from this proxy:
When there is an Origin header in the request, meaning it is a CORS request, then there are Access-Control-XX-XXX (CORS) headers in the response.
When there is no Origin header in the request, there are no Access-Control-* headers in the response.
This occurs whether there is a fault or not. In other words, Apigee is behaving as expected. (See the terminal session below) So there is something else going on wrong with yours.
Looking at your CORS policy, it may be that your Max-Age is set to 3628800, which equates to 42 days. Is it possible that your browser has cached an older version of the CORS response, and is relying on that older cache, and is never connecting with Apigee at all? If you would like to eliminate this as a possibility, use the browser developer tools and turn off the in-browser caching. (Google it if you donāt know which button to click)
Otherwise I donāt know what to suggest. Iāve attached my proxy so you can try it in your environment.
Do not use RaiseFault in a FaultRule. It is an anti-pattern (details here). If you need to set the response in a FaultRule, including in DefaultFaultRule, you should use AssignMessage.
I donāt think you should need to explicitly set a header in an AssignMessage. If you use the CORS policy, it will apply access-control header as appropriate in the response. See the bundle i attached in my prior reply. It shows the correct way.
It could be that using a RaiseFault in a FaultRule is causing the problem, which requires you to set a header in AssignMessage.