HttpApiCorsConfiguration AllowOrigins does not support multiple origins locally
Description:
Using AWS SAM locally AllowOrigins does not work as expected, it concats the list and does not choose the correct origin
Current Template:
HttpApi:
Type: AWS::Serverless::HttpApi
Properties:
CorsConfiguration:
AllowOrigins:
- "http://localhost:3000"
- "http://localhost:3002"
AllowHeaders:
- "*"
AllowMethods:
- "*"
MaxAge: 43200
AllowCredentials: true
Observed result:

Expected result:
API Gateway allows multiple origins, SAM local works differently
Thanks for reporting the issue, we will be investigating it further. Please watch this channel for more updates, and feel free to reach out.
Hi @dannymoscoso ,
I've tried to re-produce this issue locally, and when I create the following cors configuration;
CorsConfiguration:
AllowOrigins:
- "http://localhost:3000"
- "http://localhost:3002"
AllowHeaders:
- "*"
AllowMethods:
- "*"
MaxAge: 43200
AllowCredentials: true
and make the following curl call, I am getting this result;
❯ curl 'http://localhost:3000/hello' -X 'OPTIONS' -i
HTTP/1.0 200 OK
Access-Control-Allow-Origin: http://localhost:3000,http://localhost:3002
Access-Control-Allow-Methods: DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 43200
Content-Length: 0
Server: Werkzeug/1.0.1 Python/3.8.13
Date: Thu, 07 Jul 2022 14:39:43 GMT
Can you please elaborate what is the expected result for this case?
Thanks!
Experiencing the same issues here. Chrome and other browsers require Access-Control-Allow-Origin to have a single value. If the browser receives a concatenated list such as: http://localhost:3001,http://localhost:3002 it errors with the following error:
Access to fetch at 'http://127.0.0.1:3000/users' from origin 'http://localhost:3001' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains
multiple values 'https://dropz.karbonx.app,http://localhost:3001', but only one is allowed. Have the server send the header
with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource
with CORS disabled.
This is really hindering local development as I want to be able to have the origin of my production app in my config and my local origin.
For context this is my HttpApi CORS config:
CorsConfiguration:
AllowMethods:
- OPTIONS
- GET
- POST
AllowHeaders:
- 'x-apigateway-header'
AllowOrigins:
- 'https://dropz.karbonx.app'
- 'http://localhost:3001'
Not sure what more info you need. Works:
CorsConfiguration:
AllowOrigins:
- http://localhost:3000
Does not work:
CorsConfiguration:
AllowOrigins:
- http://localhost:3000
- http:test.example.com
Recreating is easy, just put more than one origin in the SAM template then attempt to test locally.
Any update on this issue? I'm still having to edit my template.yaml when working locally, then changing it back when deploying to production 😞
Any update on this issue? Just experienced it today
I'm facing the same issue with the latest version of the cli
I have similar issues using mapping. I got "Resource handler returned message: "Unable to parse the CORS configuration"
Mappings:
mymap:
urllinks:
dev:
- http://localhost:3000
- http:test.example.com
Type: AWS::Serverless::HttpApi
Properties:
CorsConfiguration:
AllowOrigins: !FindInMap [ mymap, urllinks, dev ]
This seems to be a limitation of the Access-Control-Allow-Origin header, which only allows one origin (source). There is nothing SAM could do to alter the behavior of web browsers.
The API Gateway docs (source) do mention how to deal with this problem:
Notice that the preflight response only allows one origin to call this API. To enable multiple origins with REST APIs, use ‘*’ for the allow-control-allow-origin header. Alternatively, use a Lambda function integration instead of a MOCK integration to set the header dynamically based on the origin of the caller.
So, if SAM CLI were to deal with this problem, the only way I can think of is that SAM would have to configure the API Gateway to dynamically choose the correct origin based on the incoming request. There is a Stack Overflow post here explaining some ways to do this.
@Thomas-McKanna You're correct, however that is something that AWS is expected to know, and therefore, when they write on their documentation that AllowOrigin "...can be a comma-separated list in string format", it is a reasonable expectation that they handle it in a compliant manner on the backend. In fact, I can think of a few leadership principles that this violates in addition to eroding customer trust, which is a one-way door scenario.
edit: grammar