Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →The immediate fix is to make the image bytes and the format passed to jsPDF.addImage() agree. A JPEG must begin with the JPEG start-of-image marker 0xFF 0xD8. If html2canvas produced PNG data, an incomplete buffer, or another representation while your call says "JPEG", jsPDF’s JPEG parser raises Supplied data is not a JPEG. Await the html2canvas promise, inspect the exact canvas or data URL, then either pass it as PNG or explicitly encode it as JPEG before calling addImage().
What the error actually means
jsPDF is not judging the picture’s visual appearance. Its JPEG decoder reads the first bytes of the supplied value and expects the JPEG signature 0xFFD8. When those bytes do not match, it throws the literal error Supplied data is not a JPEG. The usual cause is a format mismatch: PNG bytes are being declared as JPEG.
The format argument is a hint for interpreting input; it is not a converter. A filename ending in .jpg, a variable named jpegData, or an explicit "JPEG" argument cannot transform PNG bytes. The same principle applies to a truncated or malformed byte buffer.
Start with a minimal, correctly ordered export
html2canvas is asynchronous and returns a promise for a rendered HTMLCanvasElement. Keep that returned canvas and inspect or encode it immediately before passing it to jsPDF.
Free tools Windows power users keep installed
One-click scans. No signup required.
#1 Best Overall
- Excellent photo results with vibrant colors.
- Pack of 50 Sheets
import html2canvas from "html2canvas";
import { jsPDF } from "jspdf";
async function exportPdf() {
const element = document.querySelector("#invoice");
if (!element) throw new Error("#invoice was not found");
const canvas = await html2canvas(element, {
backgroundColor: "#ffffff",
useCORS: true
});
// Choose one matching pair. This pair uses PNG data.
const pngDataUrl = canvas.toDataURL("image/png");
const pdf = new jsPDF({ orientation: "portrait", unit: "pt", format: "a4" });
const pageWidth = pdf.internal.pageSize.getWidth();
const pageHeight = (canvas.height * pageWidth) / canvas.width;
pdf.addImage(pngDataUrl, "PNG", 0, 0, pageWidth, pageHeight);
pdf.save("invoice.pdf");
}
exportPdf().catch(console.error);
If your installed jsPDF version accepts a canvas directly, you can pass canvas with the matching format. A data URL makes the actual encoding visible and is often easier to diagnose. Confirm overload details against the jsPDF version installed in your project; the API has accepted data URLs, canvas-like inputs and other image forms, with examples for PNG, JPEG and WEBP.
Inspect the value before addImage()
For a data URL
const dataUrl = canvas.toDataURL();
console.log(dataUrl.slice(0, 40));
// data:image/png;base64,... or data:image/jpeg;base64,...
Use the MIME prefix as the first check. A prefix of data:image/png requires "PNG"; data:image/jpeg requires "JPEG". Do not infer the type from a variable name or download extension.
For bytes
function hexPrefix(bytes, count = 12) {
return [...bytes.slice(0, count)]
.map(byte => byte.toString(16).padStart(2, "0"))
.join(" ");
}
console.log(hexPrefix(new Uint8Array(buffer)));
// A JPEG normally starts: ff d8
// A PNG starts: 89 50 4e 47 0d 0a 1a 0a
If the first bytes are neither a recognized JPEG signature nor the signature for the format you intended, investigate how the buffer was created, decoded or truncated before changing the jsPDF call.
Rank #2
- Create affordable photo projects with a bright, glossy finish
- Customize photos with easy-to-use editing tools and print from your phone with HP Smart app
- FSC-certified, recyclable paper designed with sustainability in mind
- Handle durable, quick-dry photos right from the printer
- Make memories last with photos that resist fading for decades when printed with Original HP Ink
Choose a correction that matches the actual format
| What you have | Correct call | When to use it |
|---|---|---|
| PNG data URL | addImage(dataUrl, "PNG", ...) |
Best default for text, transparency and lossless output. |
| JPEG data URL | addImage(dataUrl, "JPEG", ...) |
Use when you intentionally encoded the canvas as JPEG. |
| Canvas element | Pass the canvas and a matching format supported by your jsPDF version | Convenient, but verify the installed API overload. |
| Byte buffer | Pass the buffer with the correct format or convert it first | Useful for fetch responses and binary pipelines. |
Encode the canvas as JPEG deliberately
const jpegDataUrl = canvas.toDataURL("image/jpeg", 0.85);
pdf.addImage(jpegDataUrl, "JPEG", 0, 0, pageWidth, pageHeight);
JPEG has no alpha channel. Transparent canvas areas are typically flattened against a background during encoding, so set a deliberate html2canvas backgroundColor if white (or another color) is required. JPEG can reduce image size, while PNG usually preserves sharp interface text and transparency better.
Recommended Free Tools
Keep html2canvas rendering problems separate from JPEG parsing
html2canvas reconstructs a representation from DOM and style information; it is not a literal, pixel-perfect browser screenshot. Unsupported CSS, missing fonts, SVG behavior or lazy content can cause a visual mismatch even when the bytes are valid. Fix those rendering differences separately from the jsPDF signature error.
Cross-origin images
Images loaded from another origin can make a canvas unsafe to read or export unless the image server permits it with appropriate CORS headers or an authorized proxy is used. html2canvas documentation lists useCORS (default false), proxy (default null) and allowTaint (default false), along with imageTimeout (default 15,000 ms), scale (default window.devicePixelRatio) and an onclone callback. Check the documentation matching your installed version because these are live configuration details.
Rank #3
- Photo Paper Package: 36 sheets of glossy photo paper, 8.5×11 inch, industry standard 180gsm/48lb, single-sided printing and blank back side for recording or writing something; compatible with inkjet printers and dye ink
- Glossy Finish: our glossy photo paper features its a reflective finish, that adds a professional and attractive touch and makes every picture look like a work of art; the printed photos and graphics are so outstanding
- Leave Vivid Colors: thanks to the good ink absorption of the picture paper, the printed photos come out vibrant colors and sharp details that truly come to life; remain beautiful landscapes and impressive moments forever
- Instant Dry: due to the advanced super cast coating, the ink on prints dry quickly without smearing and jamming; plus, the prints retain their vibrant color over time; makes your memories and designs shine in their full glory
- Wide Application: perfect for printing photos to record important and sweet moments, and also ideal for printing detailed graphics, various greeting cards, posters, chip bags, flyers, brochures, calendars, baby book
allowTaint does not grant permission to read tainted pixels. It concerns whether cross-origin content may taint the canvas; a tainted canvas can still fail at toDataURL() or pixel readback. Configure the image server’s CORS response, use an authorized proxy, or remove the remote image while isolating the failure.
Redirects to a CDN
A same-origin image URL that redirects to a CDN can change the effective origin. An issue report describes this as one possible useCORS edge case; treat it as a report about a particular setup, not a universal rule. Inspect the final URL in browser network tools and test the CDN response headers.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
A reliable isolation workflow
- Verify versions. Record the installed jsPDF and html2canvas versions. Examples of the error implementation come from jsPDF 2.5.1 material, while html2canvas configuration can change.
- Await the render. Do not call
addImage()before the html2canvas promise resolves. - Log the exact input. Print a data URL MIME prefix or the first bytes of the buffer immediately before
addImage(). - Use one known format. Capture a simple element with a local image, call
toDataURL("image/png"), and pass"PNG". - Add complexity incrementally. Reintroduce remote images, CSS backgrounds, SVG, lazy content and application-specific styles one at a time.
- Separate failures. If
toDataURL()itself throws a security exception or an image is absent, investigate origin and loading; changing"JPEG"to"PNG"will not fix that upstream problem.
Common symptoms and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
Error appears only with "JPEG" |
Canvas output is PNG | Pass "PNG" or encode with toDataURL("image/jpeg", quality). |
| Data URL is undefined or empty | Promise not awaited, wrong selector, or failed render | Check the element, await html2canvas, and log the returned canvas. |
SecurityError during export |
Tainted canvas from cross-origin content | Configure server CORS or an authorized proxy; do not rely on allowTaint to make pixels readable. |
| Images are missing but no JPEG parser error | Resource loading, timeout or unsupported rendering | Inspect network requests, consider useCORS, proxy and the imageTimeout setting, then test a local image. |
| First bytes look random or truncated | Corrupt conversion, base64 decoding or incomplete fetch | Trace the producer, check response completion and decode once only. |
| PDF contains a visually wrong page | html2canvas’s DOM reconstruction differs from browser pixels | Simplify unsupported CSS or adjust the cloned document with onclone; this is separate from byte-format validation. |
Scaling, pages and performance considerations
html2canvas’s default scale follows window.devicePixelRatio. Large, full-page canvases consume substantial memory; reduce scale when a smaller PDF image is acceptable, or capture sections and place them on separate pages. Calculate PDF dimensions from the canvas aspect ratio rather than hard-coding a JPEG-sized value. For multipage output, slice or render page-sized regions deliberately and add each image with coordinates that fit the selected paper size.
Rank #4
- Long lasting, professional quality prints
- Ultra smooth, bright white, heaviest weight paper
- Fast drying, smudge and water resistant surface
- The new standard for extraordinary images
PNG preserves crisp text but can produce large PDFs. JPEG quality is a trade-off: lower quality reduces bytes but introduces artifacts around text and UI edges. Test the output at the reader’s actual zoom level. A successful addImage() call does not prove that every source image loaded or that the rendering is pixel-identical.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns PNG, JPEG, WebP or PDF; it accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Only clean shots are billed: bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo documentation for request options. It also offers an MCP server with take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. Features include full-page lazy-image capture, CSS-selector elements, dark mode, device presets, retina scale, PDF controls, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture of 100 URLs per call, usage API and OpenAPI compatibility.
| Plan | Included shots | Price |
|---|---|---|
| Free | 1,000/month | $0, no card |
| Starter | 3,000 | $5 |
| Growth | 15,000 | $15 |
| Pro | 60,000 | $39 |
| Scale | 250,000 | $99 |
| Business | 1,000,000 | $249 |
Yearly billing gives two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to get 1,000 screenshots a month without a card.
Best Value
- Reliable quality and large capacity: Made from high-quality 180GSM/48lb paper, with uniform thickness and a smooth surface. Standard letter size (8.5 x 11 inches / 216 x 279 mm), 40 sheets per pack
- Fast Ink Absorption & Smudge-Proof Performance:Features advanced coating technology for ultra-fast ink absorption. It prints without smudging and reduces waiting time. Ensures crisp images right after printing, ideal for high-efficiency office and home use
- Vibrant, True-to-Life Color Reproduction:Optimized for dye ink to deliver rich, vivid colors and accurate color matching. With outstanding color fidelity, it accurately captures every image detail, ensuring precise and vivid presentation of photos, flyers, and other printed materials
- Single-Sided Glossy Finish for Stunning Visuals:Boasts a premium single-sided glossy surface that enhances color vibrancy and image clarity. Ink Absorbent Coating prevents ink penetration and ensures stable stacking, perfect for creating professional-looking prints without bulk.The blank back provides handy space for your notes or explanations
- Versatile Application Scenarios for All Your Needs:Ideal for a wide range of uses, including photo printing, promotional flyers, product brochures, classroom handouts and home crafts (like DIY chip bags). Compatible with most inkjet printers, meeting both professional and personal printing demands
FAQ
Does changing the file extension repair the error?
No. Extensions affect naming, not bytes. Encode the data in the desired format and pass the matching jsPDF format.
Can I use html2canvas for an exact browser screenshot?
Not necessarily. It reconstructs the page from DOM and styles, so unsupported rendering details can differ from what the browser displays.
What should I check when only external images fail?
Check the final image origin after redirects, response CORS headers, proxy authorization and html2canvas loading timeouts before debugging jsPDF.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchQuick 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.

