DOMException SecurityError — localStorage Access Denied
Fix localStorage SecurityError by wrapping access for disabled cookies or sandboxed iframes and falling back to memory storage.
Symptoms
- DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document
- Storage access throws in an iframe or third-party context
- The error appears only for users blocking cookies
Possible causes
- The browser blocks storage for the origin, often because cookies are disabled
- Code runs in a sandboxed or cross-origin iframe without storage access
- Access happens before a storage-access permission is granted
Diagnosis steps
Reproduce the access in a restricted context
try { window.localStorage.getItem('k'); } catch (e) { console.log(e.name); }Interpretation
A SecurityError here confirms storage is blocked rather than the key being missing.
Detect availability safely
const ok = (() => { try { localStorage.setItem('_t', '1'); localStorage.removeItem('_t'); return true; } catch { return false; } })();Interpretation
A feature-detection probe avoids throwing on every access and lets you fall back.
Root cause
Accessing window.localStorage throws SecurityError when the browser has disabled storage for the origin or document, such as with cookies blocked, sandboxed iframes, or blocked third-party storage. The throw occurs on property access, not on the value read.
Fix
Feature-detect storage once and wrap all access in a small adapter that falls back to an in-memory map, so the app keeps working when storage is unavailable.
Risk note
The in-memory fallback is not shared across tabs or reloads; do not rely on it for cross-session state.
Verify the fix
Run with cookies blocked or in a sandboxed iframe and confirm no uncaught error and the fallback engages.
Symptoms
The error “DOMException SecurityError — localStorage Access Denied” points at a specific failure mode. This guide documents the symptoms you can observe, the commands that isolate the cause, the root cause, the fix, and the checks that prove the fix works.
Observed symptoms include:
- DOMException: Failed to read the ‘localStorage’ property from ‘Window’: Access is denied for this document
- Storage access throws in an iframe or third-party context
- The error appears only for users blocking cookies
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Reproduce the access in a restricted context
try { window.localStorage.getItem('k'); } catch (e) { console.log(e.name); }
A SecurityError here confirms storage is blocked rather than the key being missing.
Step 2: Detect availability safely
const ok = (() => { try { localStorage.setItem('_t', '1'); localStorage.removeItem('_t'); return true; } catch { return false; } })();
A feature-detection probe avoids throwing on every access and lets you fall back.
Likely contributors, in order of frequency:
- The browser blocks storage for the origin, often because cookies are disabled
- Code runs in a sandboxed or cross-origin iframe without storage access
- Access happens before a storage-access permission is granted
Root Cause
Accessing window.localStorage throws SecurityError when the browser has disabled storage for the origin or document, such as with cookies blocked, sandboxed iframes, or blocked third-party storage. The throw occurs on property access, not on the value read.
The Fix
Feature-detect storage once and wrap all access in a small adapter that falls back to an in-memory map, so the app keeps working when storage is unavailable.
Watch out: The in-memory fallback is not shared across tabs or reloads; do not rely on it for cross-session state.
const storage = (() => {
try {
localStorage.setItem('__probe__', '1');
localStorage.removeItem('__probe__');
return localStorage;
} catch {
const mem = new Map();
return {
getItem: (k) => mem.get(k) ?? null,
setItem: (k, v) => mem.set(k, String(v)),
removeItem: (k) => mem.delete(k),
};
}
})();
Verify and Prevent
Run with cookies blocked or in a sandboxed iframe and confirm no uncaught error and the fallback engages.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.