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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

If an image supplied as a data URI disappears in an html2canvas export, first identify whether it is a PNG/JPEG data URI, an SVG data URI, a network image, or an SVG that references other resources. Then check whether the image finished loading and whether the browser permits it to be drawn. For a canvas you need to export, keep allowTaint: false; use useCORS: true only when the image’s final response grants CORS access, and use same-origin hosting or a proxy when it does not.

Data URIs are not all subject to the same failure rules. A self-contained raster data URI is different from a remote image, while an SVG data URI can fail because of encoding, dimensions, nested assets, browser behavior, or Content Security Policy (CSP). This guide works through those cases and explains what to check when canvas.toDataURL() fails.

What html2canvas does—and what it does not do

html2canvas does not capture the browser’s finished pixels as a normal screenshot would. It reads the DOM and CSS, then builds a canvas representation of the scene. As a result, unsupported or differently interpreted CSS can make the output differ from the live page, even when the page looks correct in the browser.

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

There are two separate questions to diagnose:

  • Did html2canvas load and render the image? If not, investigate its URI, decoding, dimensions, timing, CSP, and html2canvas options.
  • Can the resulting canvas be read or exported? If a network image was drawn without the required CORS approval, browser security marks the canvas as tainted. Calls such as toDataURL() can then fail.

A data URI is embedded in the document rather than fetched from a separate image origin, but an SVG data URI can itself refer to network resources. Do not assume that every image inside an SVG is self-contained just because the outer SVG is encoded as a data URI.

Identify exactly what image is failing

Inspect the actual source

Check the failing element’s src attribute and any CSS background-image value. Classify it before changing options:

  • data:image/png;base64,... or another raster data URI: the image data is embedded. Check that it is complete, decodable, and allowed by the page’s CSP.
  • data:image/svg+xml,...: inspect the SVG encoding, its dimensions, and whether it contains nested images, external stylesheets, or other external resources.
  • A regular https:// image URL: inspect the actual network request and its final response, including redirects and CORS headers.
  • A CSS background: apply the same origin and encoding checks as for an image element, while also checking how the CSS URL is quoted and escaped.

For a data URI in CSS, characters that can end the CSS URL or otherwise change its parsing must be escaped or encoded consistently. Quote the URL appropriately. For SVG, use a consistent percent-encoded or base64 representation rather than mixing incompatible forms.

Look inside SVGs for dependencies

An SVG may contain an <image> reference, a linked stylesheet, or another resource that is fetched separately. Check those references independently: the outer data URI does not grant permission to fetch a nested cross-origin asset. An SVG may also lack usable intrinsic dimensions. Give it appropriate width, height, and viewBox values; a zero-height SVG image can cause pattern creation to fail.

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

Check the final network response and CORS

For a network image, open the browser’s Network panel, locate the image request, and follow its redirects. The URL in your HTML is not necessarily the URL that serves the image. Inspect the final response for Access-Control-Allow-Origin and confirm that it permits the origin of the page doing the capture.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Drawing cross-origin image data without CORS approval taints the canvas; the browser then blocks reading its pixels or exporting it. Setting useCORS: true asks html2canvas to use CORS for eligible image loading, but it cannot make an image server grant permission. The final response must permit the requesting origin.

A reported html2canvas issue describes a same-origin image URL redirecting to a CDN in a case where CORS was not applied early enough. Treat that as a reported edge case, not a promise that every redirect or release behaves identically. If you control the URL, use the stable final CDN URL directly where appropriate, configure the CDN to return the required CORS header, or serve the image through a trusted proxy.

Choose html2canvas options that match the cause

For an exportable canvas, the key options are allowTaint, useCORS, and proxy. The documented defaults are allowTaint: false, useCORS: false, proxy: null, and imageTimeout: 15000.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Option When it helps Important limitation
allowTaint: false Keep this when the canvas must be readable or exported. It does not repair a blocked image; an image that cannot be safely used may be omitted.
useCORS: true Use when a network image server returns a CORS response that permits the page’s origin. It cannot grant CORS approval. Check the final response after redirects.
proxy: 'https://your-proxy.example/path' Use a suitable proxy when the remote server cannot provide the required CORS header. The proxy must be acceptable for your privacy, security, and latency needs; do not use an untrusted proxy for sensitive resources.
imageTimeout Set an appropriate wait limit for image loading; the documented default is 15000 milliseconds. A longer timeout does not fix a malformed URI, denied request, or missing CORS approval.

Do not set allowTaint: true as a workaround if you need to call toDataURL(). Allowing unsafe image drawing does not make a tainted canvas readable; it can instead leave you with a canvas you cannot export.

Wait for images and expose loading errors

Run html2canvas only after relevant images have loaded or decoding has finished. The following diagnostic example waits for ordinary <img> elements, logs html2canvas activity, and reports the capture promise’s errors. The onError callback is shown as provided in the project’s documented options; inspect console output and browser network errors as well.

const node = document.querySelector('#capture');

if (!node) {
  throw new Error('Capture target #capture was not found');
}

await Promise.all(
  [...node.querySelectorAll('img')].map(img =>
    img.complete
      ? img.decode?.().catch(() => {})
      : new Promise(resolve => {
          img.onload = img.onerror = resolve;
        })
  )
);

try {
  const canvas = await html2canvas(node, {
    allowTaint: false,
    useCORS: true,
    imageTimeout: 15000,
    logging: true,
    onError: err => console.error('html2canvas resource error', err)
  });

  const png = canvas.toDataURL('image/png');
  console.log(png);
} catch (err) {
  console.error('html2canvas capture or export failed', err);
}

Use useCORS: true in that example only if the final image response permits the page’s origin. If it does not, remove that option and arrange same-origin hosting or configure a suitable proxy. The wait covers image elements in the capture node; CSS backgrounds and resources nested inside SVGs need their own investigation and may not be represented by that selector.

Repair SVG data URIs and check CSP

Use consistent SVG encoding

Encode the SVG as a valid data URI. Percent-encode characters that would be interpreted as delimiters, or use base64 consistently. If the URI is placed in CSS, quote it and escape characters that would terminate or alter the CSS URL. If it is placed in an HTML attribute, ensure the attribute itself remains valid.

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

Give the SVG meaningful intrinsic geometry. Set width and height, and include a suitable viewBox when the drawing should scale. A valid path or shape in an SVG with unusable or zero dimensions may not produce a drawable image.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Allow the needed URI scheme under CSP

A restrictive Content-Security-Policy can block images even when the data URI is otherwise valid. Check the page’s img-src policy and permit the needed scheme—such as data: or, where applicable, blob:—only if that matches the resources your page uses and your security policy allows it. Do not loosen CSP broadly just to suppress a rendering symptom.

Account for browser-specific behavior

SVG data URI behavior can vary by browser, especially with escaped non-base64 SVG data in CSS. A project pull request discusses a Safari tainting case involving that form. Treat it as a specific compatibility warning rather than a claim that every Safari version fails. Test the actual target browsers with the same URI form and nested resources used in production.

Reduce the problem to a minimal reproduction

  1. Create a minimal same-origin page containing only the target element and one image.
  2. Try the image as an <img> with a simple raster data URI. Confirm it loads and decodes before adding html2canvas.
  3. Capture that element with allowTaint: false, then call toDataURL().
  4. Add the real SVG or CSS background next, keeping its URI encoding and dimensions explicit.
  5. Add nested SVG resources, transforms, external images, stylesheets, and other CSS one at a time.
  6. For each network resource, inspect the final request and response in the Network panel. This isolates parsing and rendering problems from CORS failures.

This sequence is useful because a blank result, an omitted image, and an export-time security exception are different symptoms. The smallest case that reproduces the failure usually reveals whether the cause is URI syntax, decoding, unsupported rendering, timing, policy, or origin security.

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

Troubleshooting by symptom

Symptom Likely cause What to check or change
Data-URI image is blank in the rendered canvas Malformed or truncated URI, image not decoded, CSP denial, unsupported rendering, or invalid SVG dimensions. Inspect the exact URI, browser console, CSP, and image load state. For SVG, verify encoding, dimensions, and nested resources.
Network image is omitted despite useCORS: true The final server response does not permit the page origin, or a redirect changes the serving origin. Follow redirects in Network tools and inspect the final response’s CORS header. Configure the image server/CDN, use its stable final URL where appropriate, or proxy it.
toDataURL() throws a security/tainted-canvas error A cross-origin resource was drawn without the required CORS approval. Keep allowTaint: false; obtain CORS approval from the final image server or route the resource through same-origin hosting or an appropriate proxy.
SVG pattern creation fails or output has no visible height The SVG may have zero or unusable intrinsic dimensions. Set valid width, height, and viewBox, then test the SVG by itself.
Image works in the page but is missing in capture html2canvas reconstructs the scene and may differ from the browser’s normal rendering; the resource may also still be loading at capture time. Wait for decoding, enable logging, inspect resource failures, and reduce the test case to the failing image and styles.
Only a browser or production policy fails Browser-specific SVG handling or a restrictive CSP may affect the URI or nested resource. Test the target browser and check img-src for the required scheme and any separately fetched resources.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If what you need is a screenshot of a public webpage rather than an export of a custom in-page DOM containing your data URI, ScreenshotNeo can return a screenshot or PDF from one GET request. It is not a drop-in renderer for arbitrary HTML already assembled inside your application; use html2canvas when that specific DOM-to-canvas result is what you need.

For example, save a screenshot of a webpage as WebP with cURL:

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

See the ScreenshotNeo API documentation for request options. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Sign up for free and get 1,000 screenshots a month with no card.

Frequently Asked Questions

Does a data URI image need `useCORS: true`?

Not simply because it is a data URI. First determine whether the SVG or other embedded content fetches separate network resources; those resources have their own origin and CORS requirements.

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.

Can `allowTaint: true` make `toDataURL()` work?

No. It does not grant permission to read a tainted canvas. Keep `allowTaint: false` when you need an exportable result.

Will html2canvas always match the screenshot I see in my browser?

No. It reconstructs the DOM and CSS rather than capturing the browser’s pixels, so unsupported CSS and resource handling can cause differences.

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.