Issue: Virtual background hosted on AWS S3 is blocked by CORS policy

We’re trying to use a virtual background without SAB (enforceVirtualBackground: true).
The image source for the virtual background is hosted on AWS S3:

stream.startVideo({
  virtualBackground: {
    imageUrl: 'https://s3.us-west-2.amazonaws.com/...'
  }
})

However, we’re encountering an issue where using a virtual background image from AWS S3 does not work reliably. We receive the following error in the browser console:

Access to image at ‘https://s3.us-west-2.amazonaws.com/images.our-website.com/virtualBackground/7977045493521-x-970092064024272900-virtualBackground?dummy=1769954936174’ from origin ‘https://images.our-website.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

GET ``https://s3.us-west-2.amazonaws.com/images.our-website.com/virtualBackground/7977045493521-x-970092064024272900-virtualBackground?dummy=1769954936174
net::ERR_FAILED

What we’ve tried so far

  1. Initially, we used “https://s3.us-west-2.amazonaws.com/… “ directly as the image source.
    This resulted in a CORS error.

  2. We then configured a Cloudflare proxy (images.our-website.com) in front of the S3 bucket.
    However, this did not resolve the issue.
    Even when loading the image through images.our-website.com, we still receive the same error:

“has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”

Question:
What is the recommended way to use images hosted on AWS S3 as virtual backgrounds without running into CORS issues?

Maybe you can help us with this, @vic.yang?

____________________________________________________

SharedArrayBuffer is disabled (enforceVirtualBackground: true)
Zoom Video SDK: 2.3.12
React: 17.0.2

await zmClient.init("en-US", `${window.location.origin}/lib`, {
    webEndpoint: window?.webEndpoint ?? "zoom.us",
    stayAwake: true,
    patchJsMedia: true,
    leaveOnPageUnload: true,
    enforceVirtualBackground: true,
    enforceMultipleVideos: {disableRenderLimits: true},
})

Hey @sergey77

Thanks for your feedback.

You can refer to the Amazon S3 documentation for guidance. Below is an example of a rule:

{
  "CORSRules": [
    {
      "AllowedOrigins": ["*"],
      "AllowedMethods": ["GET", "HEAD"],
      "AllowedHeaders": ["*"],
      "ExposeHeaders": ["ETag"],
      "MaxAgeSeconds": 3600
    }
  ]
}

Thanks
Vic

1 Like

Hi @vic.yang ,

Unfortunately, the fix you recommended didn’t work for us. We also tried enabling “Bucket Owner Enforced” instead of “ACL”, but that didn’t resolve the CORS issue either.

The only approach that worked was downloading the image on our backend, converting it to Base64, and then using the Base64 string on the frontend instead of the AWS S3 link. This solution worked for us.

FYI, the CORS issue also occurs in:
// ZoomVideo.createLocalVideoTrack
await localVideo.start(videoRef.current, { imageUrl });