October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
Amazon S3

How to Fix Cross-Origin Errors When Capturing Amazon S3 Images With html2canvas

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To capture an Amazon S3 image with html2canvas, the image response must allow your page’s origin through CORS, and html2canvas must request the image with useCORS: true. One setting alone is not enough: html2canvas cannot override the browser’s canvas security rules. If you cannot change the image server’s CORS configuration, use a carefully restricted same-origin proxy or omit the image from the capture.

Why an S3 image taints the canvas

A browser treats each scheme, host, and port combination as an origin. When a page draws an image from a different origin onto a canvas without CORS approval, the browser marks the canvas as tainted. Scripts then cannot safely read its pixels or export it with methods such as canvas.toDataURL(). MDN explains that drawing cross-origin data without CORS approval taints a canvas: MDN: CORS-enabled images.

This is why an S3 object can load visibly in a page yet be absent from a html2canvas result or cause a security error when the resulting canvas is exported. Public readability of an object and browser permission to expose its pixels to scripts are separate matters. S3 must return an appropriate Access-Control-Allow-Origin response header for the requesting page origin.

html2canvas recreates a page from browser-accessible content; it is not a browser-security bypass. Its FAQ says that cross-origin images require either useCORS: true with an appropriate server header or a proxy: html2canvas FAQ.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix the bucket you control: configure S3 CORS and html2canvas

1. Add a rule for the page’s exact origin

In the Amazon S3 console, open the bucket, go to Permissions, find Cross-origin resource sharing (CORS), and edit the CORS configuration. The console expects JSON. This narrow example permits GET and HEAD requests from one site:

[
  {
    "AllowedOrigins": ["https://app.example.com"],
    "AllowedMethods": ["GET", "HEAD"],
    "AllowedHeaders": ["*"]
  }
]

Replace https://app.example.com with the precise origin of the page running the capture: scheme, host, and port all matter. For example, an HTTP development page, a production HTTPS page, and a page on a non-default port are different origins. Add each origin that genuinely needs access as a separate entry, and keep the list as narrow as practical.

S3 matches CORS rules against the request origin, method, and requested headers; AWS states that it uses the first matching rule. The origin must match AllowedOrigins, the method must be allowed, and requested preflight headers must be allowed. See AWS S3 CORS configuration and AWS CORSRule API reference.

2. Ask html2canvas to use CORS

Use useCORS: true and leave allowTaint false when you need an exportable canvas. The image can also be marked with crossorigin="anonymous" if you load it directly using an HTML image element. The S3 response still must authorize the origin.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<div id="capture">
  <img id="hero"
       crossorigin="anonymous"
       src="https://bucket.s3.amazonaws.com/path/image.jpg"
       alt="Product illustration">
</div>

<button id="capture-button" type="button">Capture</button>
<script type="module">
  import html2canvas from "https://cdn.jsdelivr.net/npm/[email protected]/+esm";

  document.querySelector("#capture-button").addEventListener("click", async () => {
    const target = document.querySelector("#capture");
    try {
      const canvas = await html2canvas(target, {
        useCORS: true,
        allowTaint: false
      });
      document.body.appendChild(canvas);
      const png = canvas.toDataURL("image/png");
      console.log("Capture is exportable", png.slice(0, 40));
    } catch (error) {
      console.error("Capture failed", error);
    }
  });
</script>

The import pins the example to html2canvas 1.4.1; if your application uses a different version or bundler, keep its existing import mechanism and verify the configuration against that version’s documentation. Configuration options, including useCORS, proxy, allowTaint, and ignore-element controls, are documented at html2canvas configuration.

What the options do—and do not do

  • useCORS: true tells html2canvas to attempt loading an image with CORS. It cannot add permission to an S3 response that lacks the required header.
  • allowTaint defaults to false. Setting it to true may let a tainted image be drawn, but does not make the canvas readable or exportable; it is not a fix when you need a PNG, JPEG, or pixel data.
  • crossorigin="anonymous" sets the mode for a direct HTML image load. It does not configure the bucket and does not itself authorize the page.
  • imageTimeout defaults to 15,000 milliseconds in the documented configuration. Increasing a timeout can help with slow resources but cannot correct a CORS mismatch.

Verify the response rather than guessing

  1. Open browser developer tools and inspect the Network entry for the exact S3 image used in the capture. Check the final request after any redirect, not just the URL in your markup.
  2. Confirm the request’s Origin header is the page’s actual origin, such as https://app.example.com.
  3. Inspect the response headers. Access-Control-Allow-Origin must authorize that origin. For a non-credentialed design, a deliberately broad wildcard may be appropriate, but a specific origin is preferable when only one site needs access.
  4. If the browser sends an OPTIONS preflight, check that the matching S3 rule allows the requested method and all requested headers. Rule ordering matters because S3 uses the first match.
  5. Run the capture with useCORS: true. Check that the image appears, then test an export such as canvas.toDataURL("image/png") or a pixel read. A successful visual render alone does not prove that the canvas is readable.
  6. If the test still fails, temporarily exclude the S3 image and capture again. This helps isolate another cross-origin image, font, SVG, iframe, or canvas that was already tainted.

When you cannot change the S3 bucket

Use a same-origin proxy when the image server cannot return the needed CORS header. html2canvas’s proxy option is intended to load cross-origin resources through a proxy that returns them in a browser-usable way:

const canvas = await html2canvas(document.querySelector("#capture"), {
  proxy: "/image-proxy",
  allowTaint: false
});

The endpoint must actually fetch the permitted image and return its bytes with an appropriate content type; merely redirecting the browser to the same S3 URL does not solve the CORS problem. Design the proxy as a security boundary, not as a generic URL-fetching service.

  • Allow only expected image hosts, bucket paths, or object identifiers. Avoid accepting arbitrary URLs.
  • Enforce authentication or authorization if images are private.
  • Validate the response type and size, and handle redirects carefully so the proxy cannot be abused to reach internal services.
  • Set suitable caching and timeouts for your application. The proxy adds server work, latency, and an endpoint that needs maintenance.

html2canvas documents the proxy option for cross-origin content when direct CORS access is unavailable: html2canvas proxy documentation.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose the right fallback

Approach Use it when Requirement Trade-off
S3 CORS plus useCORS You control the bucket and the image response A matching CORS rule and useCORS: true Origin, method, and requested headers must match
Same-origin proxy You cannot change the image server A controlled proxy that fetches and returns the image Additional latency, server cost, and security surface
Exclude the image The image is optional in the capture Use data-html2canvas-ignore or an ignore predicate The screenshot omits that visual content

For an optional element, html2canvas supports an ignore marker:

<img data-html2canvas-ignore
     src="https://bucket.s3.amazonaws.com/path/optional.jpg"
     alt="Optional decoration">

Other browser limits that CORS settings cannot remove

Cross-origin iframes

A page cannot use html2canvas options to inspect content inside a cross-origin iframe when browser same-origin protections deny access. Capturing the outer page does not grant access to the iframe’s document. The iframe’s own application would need to provide a permitted integration or image output.

Already-tainted canvases

If a canvas elsewhere in the page has already drawn unauthorized cross-origin data, drawing that canvas into another canvas can carry the taint forward. Fixing the S3 rule for a different image does not cleanse it. Identify and correct the original resource or exclude that canvas.

Other resources in the capture

Images are not the only possible cause. Fonts, SVG references, CSS background images, and other embedded content may be fetched from a different origin and behave differently from the S3 object you inspected. Check each failing request and its final response headers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

The image displays in the page but disappears from the screenshot

Visual display only confirms that the browser could show the image; it does not establish canvas permission. Inspect the response for Access-Control-Allow-Origin, confirm it matches the page origin, then capture with useCORS: true.

useCORS: true is set, but the browser still reports CORS

Check for a scheme, host, or port mismatch, and verify that the response comes from the S3 URL or CDN actually serving the final image. Add the exact site origin to the applicable bucket rule. If the browser makes a preflight request, verify allowed methods and headers.

The S3 object URL works when opened directly

Opening a URL in a tab is not a test of whether another origin may read it through canvas. Repeat the check from the application page and inspect the cross-origin request and its response headers.

The bucket rule appears correct, but the error persists

S3 evaluates the first matching rule, so an earlier rule can affect which configuration applies. Recheck the exact origin and method in the Network panel, then inspect the final response in case a CDN, redirect, or signed URL points to a different response path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

toDataURL() throws a security exception

The canvas contains at least one resource that failed CORS approval or was already tainted. Keep allowTaint: false, remove or isolate resources one at a time, and verify that every image and embedded canvas in the capture is safe to read.

The image times out or fails to load

First verify the image URL, access permissions, and network response. The documented html2canvas imageTimeout default is 15,000 milliseconds; a longer value may help only when a valid image is slow. It will not fix a blocked request, missing CORS header, or inaccessible object.

Or skip the browser setup

If your goal is to capture a URL rather than export a canvas from your own page, ScreenshotNeo is a website screenshot API and MCP server that returns an image or PDF from one request. It is a different workflow from html2canvas: it captures the supplied page URL rather than granting your application JavaScript access to a tainted canvas. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" 
  -d access_key=YOUR_API_KEY 
  --data-urlencode url=https://stripe.com 
  -o shot.webp

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; those cleanup steps can each be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Sign up free for 1,000 screenshots a month—no card required.

Frequently asked questions

Does making an S3 object public fix CORS?

No. Public access controls whether the object can be fetched; CORS controls whether a browser page from another origin can expose the fetched response to scripts such as canvas code.

Can html2canvas capture an image inside a cross-origin iframe?

Not by changing its options. Browser same-origin restrictions still apply to iframe contents.

Is the S3 bucket itself always the server that needs configuration?

Not necessarily. If a redirect or CDN serves the final image response, inspect that response and ensure the actual serving path returns the appropriate CORS header.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.