Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
A tainted canvas is a browser security restriction, not an html2canvas option you can switch off. When a canvas contains image data from another origin without that image server’s CORS permission, the browser blocks pixel reads and exports. If you control the image host, enable CORS there and render with useCORS: true. If you do not, use an authorized same-origin proxy—or omit the image. allowTaint: true may let the image appear, but it will not make the canvas exportable.
What the tainted canvas error means
Canvas security is enforced by the browser. Drawing image data loaded from another origin without CORS approval changes the canvas to a tainted, non-origin-clean state. Code can no longer read its pixels with getImageData() or export it with toDataURL() or toBlob(). MDN explains the browser rule in its guide to using cross-origin images in a canvas.
html2canvas reconstructs a representation of the page from DOM information; it is not a literal screenshot of the browser window. Its output remains subject to browser origin rules. The library cannot grant a remote server’s permission or undo a tainted bitmap already present in the page. See the html2canvas documentation.
Diagnose where the failure happens
- Identify the failing operation. If the error is thrown during
getImageData(),toDataURL(), ortoBlob(), a tainted canvas is likely. A load or render error may instead indicate a request, network, or resource problem. - Inspect the rendered element. Check every remote image inside it, including images in nested components, and any nested
<canvas>elements. - Check the final image URL. In browser developer tools, inspect the request, redirects, and final response headers. A URL that begins on your site may redirect to a CDN on another origin.
- Confirm which origin needs permission. The image server must return an appropriate
Access-Control-Allow-Originresponse header for your page’s origin (or a permitted wildcard where appropriate). Page JavaScript cannot add this permission after the fact. - Check other browser restrictions separately. A cross-origin iframe’s document cannot be read by html2canvas, and an oversized canvas can produce blank or incomplete output for reasons unrelated to taint.
The html2canvas FAQ describes the common symptom as images not rendering and documents CORS and proxy options.
#1 Best Overall
Fix 1: Enable CORS on an image host you control
Configure the server or CDN that serves the image to return an Access-Control-Allow-Origin value that permits the origin of the page running html2canvas. For a restricted application, allow only the origins that need access rather than opening the resource broadly. The exact server configuration depends on your hosting or CDN; the important check is the response header on the image request, not merely a setting in your page.
Then ask html2canvas to load eligible images using CORS mode:
const canvas = await html2canvas(element, {
useCORS: true
});
const dataUrl = canvas.toDataURL('image/png');
The documented default for useCORS is false. Enabling it requests CORS-enabled image loading, but only the remote server can approve access. See the html2canvas configuration reference.
Rank #2
If you load an image yourself, the crossorigin attribute (or the image’s crossOrigin property set before assigning its source) selects CORS behavior; it does not grant permission by itself. The image server must still send the required header. MDN documents the crossorigin attribute.
Fix 2: Use a same-origin proxy when the host cannot be changed
If you are authorized to retrieve the remote image but cannot configure its server, route it through a backend on your own origin. html2canvas documents a proxy option; its getting-started guide describes a proxy that accepts a resource URL and returns the resource as a base64 data URI. The proxy must be implemented and deployed by your application; it is not a way to bypass access controls.
const canvas = await html2canvas(element, {
proxy: '/image-proxy'
});
Use the actual same-origin endpoint your application operates. Build the proxy defensively: validate allowed destinations, restrict schemes and hosts, prevent access to internal network addresses, enforce response-size and timeout limits, and return only content your application is permitted to fetch. Otherwise, an endpoint that accepts arbitrary URLs can become a server-side request forgery or resource-abuse risk.
Rank #3
Follow the library’s proxy guidance and verify that the endpoint returns an image in the format expected by your rendering flow.
Free tools Windows power users keep installed
One-click scans. No signup required.
Fix 3: Exclude or replace an image that is not essential
If a remote image is decorative or unnecessary, remove it from the capture or replace it with a locally hosted version you are permitted to use. This avoids drawing the resource that would taint the output. html2canvas normally skips images that would taint the canvas when allowTaint is false, so a missing image can be a deliberate safety outcome rather than proof that the whole render failed.
Why allowTaint does not fix export errors
allowTaint: true tells html2canvas it may draw an image even when doing so taints the output canvas. It does not change the browser’s rule for reading or exporting that canvas. If your next step calls toDataURL(), toBlob(), or getImageData(), that operation can still fail with a security error. The option is unsuitable when the goal is a readable, downloadable, or further-processable image.
Rank #4
The html2canvas FAQ and configuration reference describe this distinction: allowing the draw is not the same as obtaining CORS approval. Use useCORS with server permission, a safe proxy, or exclude the resource instead.
Edge cases that can make a correct-looking setup fail
Redirects to a CDN
A same-origin image URL may redirect to a different host. Inspect the final destination and its headers rather than relying on the first URL. An html2canvas issue opened in 2023 reports one setup where a same-origin URL redirected to a CDN and useCORS did not behave as the reporter expected. That is an individual report, not a universal rule; verify the deployed library version, final URL, and actual response headers before choosing a workaround.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →An existing canvas is already tainted
If the target DOM contains a canvas populated earlier with unapproved cross-origin content, html2canvas cannot make that bitmap origin-clean. Fix the code that originally draws into it, use approved source images, or avoid including that canvas in the capture. The limitation is covered in the html2canvas documentation.
Best Value
Cross-origin iframe content
html2canvas cannot access the document inside a cross-origin iframe because the browser’s same-origin policy prevents it. CORS image settings do not grant access to another frame’s DOM. If the iframe is under your control, arrange a supported capture from within that origin or provide the needed content through an authorized integration.
Blank or partial output without a SecurityError
Do not assume every blank capture is a tainted canvas. The FAQ also identifies browser canvas-size limits as a separate cause of blank or incomplete output. Reduce the capture dimensions or split a very large capture, then check whether pixel export still throws a security error.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Choose the remedy by what you control
| Situation | Remedy | Condition |
|---|---|---|
| You control the image host | Return suitable CORS headers and set useCORS: true |
The resource server must grant the requesting origin permission. |
| You cannot change the image host but operate a backend | Use a same-origin proxy | Fetch only permitted resources and validate proxy inputs. |
| The image is not required | Exclude or replace it | Do not rely on allowTaint if the result must be readable or exportable. |
Or skip the browser setup
If the goal is a website screenshot rather than rendering a particular DOM node, ScreenshotNeo can return a screenshot or PDF through one API request. Its capture flow accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and responses report the page verdict and billing status. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for AI agents and MCP clients.
Install Python’s requests package, set your API key, and run this example (change the target URL as needed):
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
See the ScreenshotNeo API documentation for request options. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, with no card required.
Troubleshooting checklist
SecurityErroron export: inspect every drawn remote image and nested canvas; confirm the final image response has appropriate CORS permission.useCORS: truebut image still absent: check the actual request mode, final redirected host, response headers, and browser network errors. The option cannot repair a server response that withholds permission.- Adding
crossorigin="anonymous"changes nothing: configure the image server too; the attribute alone grants no access. allowTaint: truemakes the image appear but export fails: expected browser behavior. Use CORS, a proxy, or exclude the image.- Image loaded from a same-site URL but is treated as cross-origin: inspect redirects and the final response origin.
- Nested canvas triggers the problem: trace how it was populated; html2canvas cannot clear its prior taint.
- Iframe content is missing: if it is cross-origin, browser security blocks access to its document; image CORS settings do not change that.
- Output is blank or clipped without an export error: investigate canvas dimensions and browser size limits as a separate issue.
Frequently Asked Questions
Can JavaScript remove the tainted state from a canvas?
No. Once unapproved cross-origin image data has been drawn, the browser does not let page code make that canvas origin-clean again. Render from approved sources or create a new canvas without the tainting content.
Does html2canvas capture the browser screen exactly?
No. It builds a canvas representation from DOM information, so it is subject to resource access and rendering limitations rather than acting as a literal screen capture.
Recommended Free Tools
Quick Recap
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.

