I keep getting 'Access-Control-Allow-Origin' header contains multiple values '*, *'
when using fetch
API to get images from my cloudfront cdn. A sample URL that demonstrates this problem is https://cdn.dev.textras.com/images/6158ac8f8074530013f8dcde/77b4b530-738c-11ec-ae4a-1d90956db63a.jpeg?w=320&q=100&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYxNTFiZTZkMDJkYmM3MDAxNDIzMDhhZiIsImNvdW50cnlDb2RlIjoiTkdBIiwiaWF0IjoxNjQzMjE4ODE2LCJleHAiOjE2NDM0NzgwMTZ9.m2zcZJ0pv-Sj1q7Mz8w9GNoxzLiHBSCf3Yd8qu-YE4s
. If you use that url as the src
for an <img>
tag, the image loads. If you visit the URL in a browser tab, the image loads. If you open dev tools within that same tab and then do a fetch
request to get the image (i.e. same origin), the fetch
request succeeds. If you request the image using postman or curl
from the terminal, the request succeeds. However if you're in a browser tab with a domain different from my cdn (i.e. cross origin), it doesn't load. There are lots of questions about this on the internet and the root cause is always that the server is setting the header multiple times in different places. However, I'm unable to identify where this is happening in my case. This is a snippet from the template that defines the behavior of the cloudfront distribution. I'm only including the part that defines the behavior that affects this particular image:
...
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Aliases: !Ref AliasesParam
Comment: !Ref Comment
CacheBehaviors:
- AllowedMethods: "DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT"
CachedMethods: "GET,HEAD,OPTIONS"
Compress: false
PathPattern: 'videos/thumbnails/*'
DefaultTTL: "1814400"
ForwardedValues:
QueryString: true
QueryStringCacheKeys:
- w
- h
- t
- q
- v
LambdaFunctionAssociations:
- EventType: 'viewer-request'
LambdaFunctionARN: !Ref ViewerRequestFunctionVersionArn
- EventType: 'origin-request'
LambdaFunctionARN: !Ref LambdaVideoPathEdgeVersionArn
- EventType: 'origin-response'
LambdaFunctionARN: !Ref OringResponseFunctionVersionArn
MaxTTL: 31536000
MinTTL: 0
SmoothStreaming: false
TargetOriginId: !Ref IdParam
ViewerProtocolPolicy : "redirect-to-https"
# TrustedSigners:
# - String
You can see that the template doesn't specify a response header policy, so I'm sure the duplication is not happening from here. I've checked the CORS config on the s3 bucket and it's this:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"POST",
"GET",
"PUT",
"DELETE",
"HEAD"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"String"
],
"MaxAgeSeconds": 3000
}
]
So the s3 bucket sets the header.
The associated origin-response
lambda was setting this header too, like this:
response.headers['Access-Control-Allow-Origin'] = [
{ key: 'Access-Control-Allow-Origin', value: '*' },
];
I thought this may be the source of the duplication so I commented it out, but the error remained. So the way I'm looking at this is: out of the 3 places that could be setting the header's value (cloudfront distribution, origin s3 bucket, and the lambda for processing image) there's only one place still setting this CORS header, and it's the s3 bucket. Yet the problem is still happening. What other place can/should I look at? Thanks!
I would suggest reaching out to AWS Support and creating a ticket to have an engineer look at this issue.