Resolve PDF viewer issues easily
Troubleshoot common issues you might encounter when setting up the document viewer:
Common load errors
When the viewer fails to load, check the browser console for specific error messages. Here’s how to diagnose load issues:
try { const instance = await NutrientViewer.load({ container: "#pspdfkit", document: "document.pdf", licenseKey: "YOUR_LICENSE_KEY" }); console.log("Viewer loaded successfully");} catch (error) { console.error("Failed to load viewer:", error.message);
// Check for specific error types. if (error.message.includes("container")) { console.error("Container element not found. Ensure the element exists in the DOM."); } else if (error.message.includes("document")) { console.error("Document could not be loaded. Check the file path and format."); } else if (error.message.includes("network")) { console.error("Network error. Check your internet connection and server status."); }}Common causes:
- The container element doesn’t exist in the DOM when
load()is called. - The document path is incorrect or the file doesn’t exist.
- Required assets (WebAssembly files) aren’t accessible.
- The document is corrupted or in an unsupported format.
CORS issues
Cross-origin resource sharing (CORS) errors occur when loading documents or assets from a different domain. Check for CORS issues in the browser console:
// Diagnose CORS issues.async function loadWithCORSDiagnostics() { const documentUrl = "https://example.com/document.pdf";
// First, test if the document is accessible. try { const response = await fetch(documentUrl, { method: "HEAD" }); if (!response.ok) { console.error(`Document not accessible: HTTP ${response.status}`); return; } } catch (error) { console.error("CORS or network error:", error.message); console.error("Ensure the server includes these headers:"); console.error(" Access-Control-Allow-Origin: *"); console.error(" Access-Control-Allow-Methods: GET, HEAD"); return; }
// If fetch succeeds, proceed with loading. try { const instance = await NutrientViewer.load({ container: "#pspdfkit", document: documentUrl, licenseKey: "YOUR_LICENSE_KEY" }); } catch (error) { console.error("Viewer load error:", error); }}Solutions:
- Configure your server to send proper CORS headers:
Access-Control-Allow-Origin: *. - Use a proxy server to serve documents from the same origin.
- For local development, use a local server instead of
file://URLs.
License problems
License errors prevent the viewer from functioning correctly. Here’s how to identify and resolve license issues:
NutrientViewer.load({ container: "#pspdfkit", document: "document.pdf", licenseKey: "YOUR_LICENSE_KEY"}).then(instance => { console.log("License valid, viewer loaded");}).catch(error => { if (error.message.includes("license")) { console.error("License error detected:", error.message);
// Common license issues console.log("Troubleshooting steps:"); console.log("1. Verify the license key is correct (no extra spaces)"); console.log("2. Check if the license has expired"); console.log("3. Ensure the domain matches your license"); console.log("4. For trial licenses, check usage limits"); }});Common license issues:
- Invalid key — Typos or extra whitespace in the license string
- Domain mismatch — License is bound to a different domain
- Expired license — Trial or subscription has ended
- Feature not licensed — Attempting to use features not included in your license tier
For license-related questions, contact Nutrient support.
Memory warnings
Large documents or extended use can cause memory issues. Monitor and manage memory usage:
// Monitor memory usage (Chrome only).function checkMemoryUsage() { if (performance.memory) { const used = Math.round(performance.memory.usedJSHeapSize / 1048576); const total = Math.round(performance.memory.totalJSHeapSize / 1048576); const limit = Math.round(performance.memory.jsHeapSizeLimit / 1048576);
console.log(`Memory: ${used}MB used / ${total}MB allocated / ${limit}MB limit`);
if (used > limit * 0.8) { console.warn("High memory usage detected!"); } }}
// Properly unload the viewer when done.function cleanupViewer(instance) { if (instance) { NutrientViewer.unload(instance); console.log("Viewer unloaded, memory freed"); }}
// Example: Load with memory management.let viewerInstance = null;
async function loadDocument(documentPath) { // Unload previous instance first. if (viewerInstance) { cleanupViewer(viewerInstance); }
viewerInstance = await NutrientViewer.load({ container: "#pspdfkit", document: documentPath, licenseKey: "YOUR_LICENSE_KEY" });
checkMemoryUsage(); return viewerInstance;}Best practices:
- Always call
NutrientViewer.unload()when switching documents or unmounting components. - Avoid loading extremely large documents (100+ MB) on memory-constrained devices.
- Consider using streaming for large documents.
- Monitor memory in development using browser DevTools.
WebAssembly failures
Nutrient Web SDK uses WebAssembly for document rendering. WebAssembly issues can prevent the viewer from loading:
// Check WebAssembly support before loading.function checkWebAssemblySupport() { try { if (typeof WebAssembly === "object" && typeof WebAssembly.instantiate === "function") { // Test basic WebAssembly functionality. const module = new WebAssembly.Module( Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00) ); if (module instanceof WebAssembly.Module) { console.log("WebAssembly is supported"); return true; } } } catch (e) { console.error("WebAssembly check failed:", e); }
console.error("WebAssembly is not supported in this browser"); return false;}
// Load with WebAssembly diagnostics.async function loadWithWasmDiagnostics() { if (!checkWebAssemblySupport()) { alert("Your browser doesn't support WebAssembly. Please use a modern browser."); return; }
try { const instance = await NutrientViewer.load({ container: "#pspdfkit", document: "document.pdf", licenseKey: "YOUR_LICENSE_KEY" }); return instance; } catch (error) { if (error.message.includes("wasm") || error.message.includes("WebAssembly")) { console.error("WebAssembly error:", error.message); console.log("Possible causes:"); console.log("1. WASM files not found - check baseUrl configuration"); console.log("2. Server not serving .wasm with correct MIME type"); console.log("3. Content Security Policy blocking WASM execution"); } throw error; }}Common WebAssembly issues:
- Missing MIME type — Ensure your server serves
.wasmfiles with theapplication/wasmMIME type. - CSP restrictions — Add
'wasm-unsafe-eval'to your Content-Security-Policy if needed. - Asset path incorrect — Verify
baseUrlpoints to the correct location of Nutrient assets. - Browser compatibility — Use a supported browser.
Server configuration examples:
For Apache (.htaccess):
AddType application/wasm .wasmFor Nginx:
types { application/wasm wasm;}For Node.js/Express:
app.use(express.static("public", { setHeaders: (res, path) => { if (path.endsWith(".wasm")) { res.set("Content-Type", "application/wasm"); } }}));Microsoft Edge with Enhanced Security Mode
Microsoft Edge versions before 144.0.3719.92 had a bug that caused the Web SDK to fail when Enhanced Security Mode was enabled. This issue is now fixed.
Solution
Update Microsoft Edge to version 144.0.3719.92 or later. Edge updates automatically, but you can manually check for updates:
- Go to
edge://settings/help - Edge will check for and install any available updates
- Restart the browser
Symptoms
If you’re on an older Edge version with Enhanced Security Mode enabled, you may see:
- SDK fails to initialize with
std::bad_allocexception - Console shows “memory access out of bounds” errors
Workarounds for older versions
If you can’t update Edge immediately, use one of these workarounds.
For end users — Add your application’s domain to the Enhanced Security allow list:
- Go to
edge://settings/privacy - Under Enhance your security on the web, click Exceptions
- Add your application’s domain
For developers/testing — Launch Edge with flags to disable the problematic optimization:
# macOS/Linux/path/to/msedge --js-flags="--jitless --wasm-jitless --no-drumbrake-register-optimization"
# Windows"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --js-flags="--jitless --wasm-jitless --no-drumbrake-register-optimization"Background
This was caused by a bug in Chromium’s DrumBrake WebAssembly interpreter, which Edge uses when Enhanced Security Mode disables JIT compilation. The bug affected register optimization for complex WASM binaries. See Chromium Issue #477318781(opens in a new tab) for details.