So many acronyms in that title - I promise you they actually make sense!

I was doing some local development against an AWS SAM-based API built with an AWS API Gateway HTTP APIs (not to be confused with the REST APIs), and the error message I was getting really didn't help me find the solution:

Access to fetch at 'https://id123456.execute-api.us-east-1.amazonaws.com/' from origin 'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Contrary to the error message, setting the request's mode to no-cors is a terrible idea that will simply stop any CORS requests from working. CORS is a key part of browser security that stops them from loading malicious code from other (potentially bad) servers; though it's very useful, it's often very frustrating.

In addition to the HTTP API, I was using a Cognito Authorizer and passing my JWT as a bearer token in the Authorization header. The issue was that in my SAM configuration for my HTTP API I hadn't included header in in the optional AllowHeaders section of the the API's CorsConfiguration. Adding it alongside the HTTP method I actually wanted to use was enough to get me past the issue, no thanks to the opaque error message:

      CorsConfiguration:
        AllowOrigins:
          - http://localhost:5173
        AllowMethods:
          - GET
        AllowHeaders:
          - Authorization

This issue was really hard to search for, and most results I found were for the older REST APIs.