Browser errors
Status: đ© COMPLETE Last updated: 2026-06-21 Plain-English tagline: What the browserâs console shows when somethingâs wrong â CORS, hydration, mixed content, the âuncaught Xâ series. Paste the fragment, find the fix.
What this is
A lookup reference for errors that show up in the browser console (F12 â Console tab) or as in-page errors. Most are runtime issues â they happen when your code runs in the browser, not at build time. For build errors, see Build errors đ©.
âCross-Origin Request Blockedâ / âCORS errorâ
What it means: Your page at https://a.com made a request to https://b.com, and b.com didnât say itâs OK with that.
The mental model: browsers treat every origin (scheme + domain + port) as separate. By default, JavaScript on one origin canât read responses from another. The server has to explicitly opt in via CORS headers.
Common situations and fixes:
-
Calling your own API from your own frontend â should âjust workâ since same origin. If it doesnât: check that youâre using a relative path (
/api/x) not an absolute one (https://example.com/api/x). -
Calling a third-party API from the browser â the API needs to return:
Access-Control-Allow-Origin: https://your-site.comIf they donât (or only allow
*for public endpoints): proxy through your own server. Route the call through a Next.js Server Action or Route Handler. -
Local dev calling a deployed API â the deployed API may CORS-allow
https://your-site.combut nothttp://localhost:3000. Add localhost to the allow list (server-side config), or proxy vianext dev. -
âIt works in Postman/curl but not in the browserâ â Postman/curl donât enforce CORS. Browsers do. The API may need updated headers.
Reference: How the web works â Same-origin policy and CORS đ©
âHydration failed because the initial UI does not matchâ
What it means: Next.js / React server-rendered HTML, then the client re-rendered, and the two didnât match. React refuses to silently fix it.
Most common causes:
- Time / date in render.
new Date().toString()is different on server vs client. - Random values.
Math.random()in render. - Browser-only APIs.
window.innerWidth,localStorage.getItem(...)used directly in render. - Conditional rendering based on browser state.
typeof window !== "undefined" ? A : B. - External HTML manipulation. Browser extensions or analytics scripts inserting elements before hydration.
Fix:
- Move dynamic / browser-specific code into
useEffect(which only runs on the client after mount). - Or move the component into a Client Component (
"use client") AND render a stable placeholder during SSR. - For browser extensions: usually not your bug, but you can suppress for known cases with
suppressHydrationWarning={true}.
// BEFORE (causes hydration error)
function TimeDisplay() {
return <p>{new Date().toLocaleTimeString()}</p>;
}
// AFTER
"use client";
import { useEffect, useState } from "react";
function TimeDisplay() {
const [time, setTime] = useState("");
useEffect(() => {
setTime(new Date().toLocaleTimeString());
}, []);
return <p>{time}</p>;
}Reference: Next.js â common gotchas đ© đŠ, The DOM â hydration đ©
âMixed Content: The page was loaded over HTTPS, but requested an insecure resourceâ
What it means: Your HTTPS page tried to load something over HTTP. Browsers block this â it would defeat HTTPS.
Fix: change every http:// URL in your code to https:// (or remove the scheme to use protocol-relative: //example.com/image.png). This includes:
<img src>,<script src>,<link href>- API calls
- Iframe sources
- Background images in CSS
If the resource genuinely only exists over HTTP (legacy server), youâll have to proxy it through HTTPS or upgrade the source.
Reference: How the web works â HTTPS đ©, HTTPS đ©
âUncaught (in promise) TypeError: Failed to fetchâ
What it means: A fetch() call rejected before getting a response. Usually network / CORS / DNS / connection issue.
Common causes:
- Network is offline.
navigator.onLinecan tell you. - CORS preflight failed. The browser sent an OPTIONS request and didnât get a valid response.
- DNS / unreachable host. The URL is wrong or the server is down.
- Local dev server stopped. Youâre calling
localhost:3000butnpm run devisnât running. - Self-signed cert in production-like env. Browser refuses to trust the connection.
Fix: check the Network tab in DevTools â it shows the actual request that failed and why. The Console error alone is often vague.
âRefused to load the script because it violates the following Content Security Policyâ
What it means: A Content Security Policy (CSP) header on the page forbids loading scripts from this source.
Fix:
- For your own scripts: add the source to the CSP, or move the script inline (if CSP allows
unsafe-inline). - For third-party scripts (analytics, embeds): add their domain to
script-srcin the CSP header. - For development: check
next.config.jsorvercel.jsonfor CSP settings.
CSP is good for security but easy to over-tighten. Loosening it requires care.
âResizeObserver loop completed with undelivered notificationsâ
What it means: A ResizeObserver callback caused a layout change that triggered another resize, which couldnât be processed in the same frame.
Almost always: this is a harmless warning. Browsers protect against the loop and drop the callback. The next frame processes it normally.
Fix:
- Ignore it in most cases. Itâs a âloud nothing.â
- If it causes visible flicker: the callback is likely setting state that resizes the same element. Restructure so size changes happen via different mechanisms (CSS variables, debounced updates).
This error is so noisy in production that many monitoring tools (Sentry, etc.) ignore it by default.
âMaximum update depth exceededâ
What it means: A React component is in an infinite render loop. Usually setState inside the render body, or useEffect updating its own dependency.
Common causes:
// BAD: setState in render body
function Component() {
const [x, setX] = useState(0);
setX(1); // re-renders â setX(1) â re-renders â ...
return <div>{x}</div>;
}
// BAD: useEffect missing dependency check
useEffect(() => {
setUser({ ...user, foo: true }); // new object identity every render
}, [user]); // user "changed" â re-run â ...Fix:
- Move
setStatecalls into event handlers, effects, or callbacks â never directly in render body. - For effects that update their dependency: either remove the dependency, use a guard (
if (user.foo) return), or use the function-form setter (setX(x => x + 1)).
Reference: React â common gotchas đ©
âWarning: Each child in a list should have a unique âkeyâ propâ
What it means: Youâre rendering a list (array.map(...)) without setting a stable key on each child.
Fix:
// BAD
{items.map(item => <li>{item.name}</li>)}
// OK (but only if order never changes)
{items.map((item, i) => <li key={i}>{item.name}</li>)}
// BEST
{items.map(item => <li key={item.id}>{item.name}</li>)}Why it matters: without keys, React canât efficiently update the list â it may re-create DOM nodes instead of moving them. Symptoms include lost form input state, broken animations, and the unhelpful warning above.
âUncaught TypeError: Cannot read properties of undefined (reading âXâ)â
What it means: Same as the build-time version, but happening at runtime: you tried to access .X on undefined.
Fix:
- Add optional chaining:
obj?.Xreturnsundefinedinstead of crashing. - Add a guard:
if (obj) { obj.X }. - Find the source: the error stack tells you which line. Work backwards from there â where was
objsupposed to be set?
For arrays: Array.isArray(x) && x.length > 0 before accessing x[0].
âFailed to load resource: net::ERR_BLOCKED_BY_CLIENTâ
What it means: A browser extension (most often an ad blocker) blocked the resource.
Fix: usually not your codeâs fault. But:
- If itâs analytics, ads, or trackers: expected.
- If itâs your own resource named like a tracker (e.g.
analytics.js,track.js): rename it. Ad blockers match on filename heuristics. - Test in an incognito window with extensions disabled to confirm.
âLoading chunk N failedâ / âChunkLoadErrorâ
What it means: Code-splitting tried to load a JavaScript chunk thatâs no longer available. Usually after a fresh deploy when the userâs tab is on the old version.
Fix:
- In production: prompt the user to refresh. Wrap dynamic imports in a try/catch and show a âwe updated; please refreshâ message.
- To prevent: Next.js + Vercel handle this for most users via consistent chunk hashing across deploys. But long-lived tabs can still hit it.
async function loadHeavyComponent() {
try {
return await import("./HeavyComponent");
} catch (e) {
window.location.reload(); // simplest recovery
}
}âBlocked a frame with origin âXâ from accessing a cross-origin frameâ
What it means: Your iframe (or a parent of yours) tried to read/manipulate content from a different origin.
Fix: there isnât a one. The same-origin policy explicitly prevents this. If you control both sides, use postMessage for cross-origin communication. If you donât control both, you canât access the other sideâs content.
âPermissions policy violation: âŠâ
What it means: A Permissions Policy header restricts a browser feature (camera, microphone, geolocation, etc.) and your code tried to use it.
Fix:
- For your own page: add the permission to your Permissions Policy header (
Permissions-Policy: camera=(self)). - For embedded iframes: the embedder controls what the iframe can do.
âHydration completed but contains mismatchesâ
What it means: A milder variant of the hydration error â Next.js / React noted a mismatch but recovered. Page works, but the warning indicates an underlying issue worth fixing.
Fix: same as full hydration failure above â find time/random/browser-API uses in render.
âSource map error: NetworkError when attempting to fetch resourceâ
What it means: DevTools tried to fetch a .map file for debugging and failed (file missing, behind auth, etc.).
Fix: usually safe to ignore. In production, source maps are often not deployed. If you need them: configure Next.js to deploy them (productionBrowserSourceMaps: true in next.config.js).
See also
- Common errors â index đ©
- Build errors đ©
- Supabase errors đ© đŠ
- Git errors đ©
- How the web works đ© â the conversation model behind CORS, HTTPS, etc.
- The DOM đ©
- React â common gotchas đ©
- Next.js â common gotchas đ© đŠ
- HTTPS đ©
- OWASP top 10 đ©