See exactly what your DNS blocker is blocking — and why it matters.
A browser extension for Chrome, Firefox, Firefox for Android, and Safari that watches your network traffic in real-time, identifies domains blocked by NextDNS, Pi-hole, or Control D, and tells you the functional impact — whether a block might break login, stop videos from loading, prevent checkout, hide maps, or silence support chat.
NextDNS, Pi-hole, and other DNS-level blockers work great for privacy, but they can cause subtle breakage on websites. A feature flag service gets blocked, and suddenly an inventory page won't load. An auth provider is blocked, and login silently fails. A payment processor is blocked, and checkout never completes. You reload the page six times wondering what's wrong, never knowing DNS was the culprit.
This extension makes that visible — and tells you exactly what's at stake.
- Monitors network errors on every tab using the browser's
webRequestAPI - Identifies DNS-block signatures — certificate issuer failures, name resolution errors, and other patterns that indicate a DNS-level block (not a server error or timeout)
- Classifies every blocked domain against a database of 561 known services across 27 categories, grouped by how likely they are to break site functionality:
- 🔴 High — Feature flags, authentication, payment processors, search APIs, core CDNs, CAPTCHA. These break sites.
- 🟡 Medium — Support chat, video players, maps, image CDNs, error monitoring, e-commerce. May affect functionality depending on the site.
- 🟢 Low — Pure analytics and advertising. Almost never affects how a site works.
- Shows a functional impact badge on every blocked domain — so you know at a glance what breaks, not just that something broke
- Attributes the block to a specific blocklist — works for both NextDNS (from the logs API) and Pi-hole v6 (via the gravity search API, with pretty names for 30+ common lists)
- Confirms DNS routing — a live status chip in the header shows whether your browser is actually sending DNS through your selected provider (green = active, red = not routing)
- Unknown domains fall back to Medium — worth reviewing, but not necessarily critical
- Badge updates on the extension icon: count of blocked domains, red = high-risk detected
Click the extension icon on any page to see:
- Stats bar — counts of High / Medium / Low blocked domains; click any level to filter
- Impact badge — color-coded tag on every domain showing the functional consequence of blocking it (see Impact Badges below)
- Blocklist attribution — which blocklist rule flagged the domain (HaGeZi, AdGuard, uBlock Origin, etc.)
- Grouped list — blocked domains sorted by risk, showing service name, error type, and hit count
- 📋 Copy button — copies the domain to clipboard; works with NextDNS, Pi-hole, AdGuard, or any DNS blocker
- + Allowlist button — one click adds the domain to your NextDNS, Pi-hole, or Control D allowlist (requires credentials)
- DNS flush reminder — appears after every allowlist/copy action with the exact command for your OS
- DNS routing status chip — green/red indicator in the header confirming your DNS is actually going through the selected provider
- Profile indicator — NextDNS profiles are fingerprint-matched; your current device's profile is labeled "This device"
Every blocked domain carries a color-coded badge showing the functional impact of the block — not just how risky it is, but specifically what it might break:
| Badge | Color | What it means | Example categories |
|---|---|---|---|
| login/forms | 🔴 Red | Could prevent login, registration, or form submission | Auth, payments, CAPTCHA |
| media/maps/assets | 🔵 Blue | Could break video playback, maps, or page assets | Video players, maps, image CDNs, CDN |
| chat | 🟢 Green | Could hide or disable support chat widgets | Support chat, real-time |
| feature flags | 🟣 Purple | Could silently change or disable site features | Feature flags |
| search | 🩵 Cyan | Could break search or autocomplete | Search APIs |
| monitoring | ⚫ Black | Could disable error reporting or observability | Error monitoring |
These badges are independent of the High/Medium/Low risk rating — a "Low" domain can still carry a monitoring badge so you know what's affected.
Chrome: Load unpacked via chrome://extensions → Developer mode → Load unpacked (select the folder)
Firefox: Load via about:debugging → This Firefox → Load Temporary Add-on (select the zip)
Firefox for Android: Install Firefox Nightly → open about:config → set xpinstall.signatures.required to false → open about:Firefox → tap the logo 5× to unlock debug menu → Install Extension from File → select the .xpi
Safari (macOS): Download dns-medic-safari-macOS-v*.zip from Releases → unzip → drag DNS Medic.app to Applications → right-click → Open (required once to bypass Gatekeeper) → Safari → Develop → Allow Unsigned Extensions → Safari → Settings → Extensions → enable DNS Medic.
Note: "Allow Unsigned Extensions" resets every time Safari quits — re-enable it each session until the Mac App Store version is available.
Chrome and Firefox desktop will be available on their respective extension stores once reviewed.
Click the extension icon → ⚙️ Settings → select your provider:
NextDNS
- API Key — found at my.nextdns.io → Account → API; hit → to load profiles
- The extension fingerprint-matches your device to the right profile and labels it "This device"
Pi-hole
- URL — e.g.
http://pi.holeor your Pi-hole's IP address - API Token — Pi-hole v6: your web UI password · Pi-hole v5: Settings → API
- Both Pi-hole v5 and v6 are auto-detected
Control D
- API Token — generate at controld.com → Account → API Tokens (use Write permission)
- Hit → to load your profiles and select the one to allowlist into
Without credentials the extension still monitors and classifies — you just won't have the one-click allowlist button. Use the 📋 copy button to manually add domains in your DNS blocker's dashboard.
| Browser | Manifest | Background | Status |
|---|---|---|---|
| Chrome 109+ | MV3 | Service Worker | ✅ Supported |
| Firefox 140+ | MV2 | Background Scripts | ✅ Supported |
| Firefox for Android | MV2 | Background Scripts | ✅ Supported |
| Safari (macOS) | MV2 | Background Scripts | ✅ Supported (Beta) |
| Edge | MV3 | Service Worker | ✅ Should work (untested) |
Firefox note: Requires Firefox 140+ due to use of the data_collection_permissions manifest field. NextDNS blocks appear as certificate issuer errors in Firefox (e.g. "Peer's Certificate issuer is not recognized"). The extension detects these correctly, including the curly-apostrophe variant (U+2019) that Firefox uses internally.
Firefox for Android: Install via Firefox Nightly. Enable debug mode: about:Firefox → tap the logo 5× → Install Extension from File. The popup is fully responsive and fills the panel width on mobile.
Safari (macOS): Detects blocked requests using Safari's ERR_ABORTED signal. Known tracker domains are classified immediately; unknown aborted domains appear in a separate ⚪ Unverified section. For NextDNS users, unverified domains are automatically confirmed using the NextDNS logs API when the popup is opened. Note: "Allow Unsigned Extensions" resets every time Safari quits — re-enable it each session until the Mac App Store version is available.
The extension ships with a bundled database of 561 entries across 27 categories and automatically fetches updates from this repository. The database is cached locally for 7 days and can be force-refreshed from the Settings panel at any time.
| Category | Examples | Risk | Impact Badge |
|---|---|---|---|
| Feature Flags | Statsig, LaunchDarkly, Split.io, Optimizely, PostHog, GrowthBook, ConfigCat | 🔴 High | 🟣 feature flags |
| Authentication | Auth0, Okta, Clerk, Kinde, Stytch, WorkOS, Firebase Auth, AWS Cognito, Azure AD | 🔴 High | 🔴 login/forms |
| Payment Processors | Stripe, Braintree, PayPal, Klarna, Adyen, Affirm, Afterpay, Square | 🔴 High | 🔴 login/forms |
| Search APIs | Algolia, Constructor.io, Searchspring, Klevu, Bloomreach, Coveo, Yext | 🔴 High | 🩵 search |
| CDN | Cloudflare, Fastly, Akamai, jsDelivr, unpkg, Google APIs, AWS | 🔴 High | 🔵 media/maps/assets |
| Real-time / WebSocket | Pusher, Ably, Twilio, LiveKit, Daily.co, Agora | 🔴 High | 🟢 chat |
| CAPTCHA | reCAPTCHA, hCaptcha, Turnstile, FunCAPTCHA, GeeTest | 🔴 High | 🔴 login/forms |
| A/B Testing | VWO, AB Tasty, Convert.com, Kameleoon, Optimizely Web | 🔴 High | 🟣 feature flags |
| Video Players | YouTube Embed, Vimeo, Wistia, Mux, Brightcove, JW Player, Kaltura | 🟡 Medium | 🔵 media/maps/assets |
| Maps | Google Maps, Mapbox, HERE Maps, MapTiler, OpenStreetMap tiles | 🟡 Medium | 🔵 media/maps/assets |
| Support Chat | Intercom, Zendesk, HubSpot, Drift, Crisp, Freshchat, LiveChat | 🟡 Medium | 🟢 chat |
| Notifications | OneSignal, Pushwoosh, Airship, Braze, Iterable, Attentive, Klaviyo | 🟡 Medium | 🟢 chat |
| Image CDNs | Cloudinary, Imgix, Fastly Image Optimizer, Thumbor, ImageKit | 🟡 Medium | 🔵 media/maps/assets |
| Error Monitoring | Sentry, Datadog RUM, New Relic, Bugsnag, Rollbar, Raygun | 🟡 Medium | ⚫ monitoring |
| Session Replay | Hotjar, FullStory, LogRocket, Mouseflow, Lucky Orange, Contentsquare | 🟡 Medium | ⚫ monitoring |
| E-commerce | Shopify, Affirm, Klarna widgets, Yotpo, Bazaarvoice, Stamped | 🟡 Medium | 🔴 login/forms |
| Reviews | Yotpo, Bazaarvoice, Trustpilot, Okendo | 🟡 Medium | 🔵 media/maps/assets |
| Headless CMS | Contentful (ctfassets.net), Storyblok, Sanity, DatoCMS | 🟡 Medium | 🔵 media/maps/assets |
| Tag Manager | Google Tag Manager, Tealium, Ensighten, Segment | 🟡 Medium | ⚫ monitoring |
| Consent | Cookiebot, Quantcast Choice, OneTrust, TrustArc | 🟡 Medium | 🔴 login/forms |
| Analytics | Google Analytics, Mixpanel, Amplitude, Segment, Heap, Chartbeat | 🟢 Low | ⚫ monitoring |
| Advertising | Google Ads, Facebook Pixel, AdRoll, Taboola, Outbrain | 🟢 Low | ⚫ monitoring |
| Animation | LottieFiles (lottie.host) | 🟡 Medium | 🔵 media/maps/assets |
| Localization | Crowdin CDN | 🟡 Medium | 🔵 media/maps/assets |
| Call Tracking | CallRail, CallTrackingMetrics, WhatConverts | 🟢 Low | ⚫ monitoring |
| SEO | Semrush, Moz, similar SEO toolbars | 🟢 Low | ⚫ monitoring |
The database is maintained in domain-db.json in this repo. On first load the extension fetches the latest version and caches it for 7 days. If the fetch fails for any reason, the bundled fallback is used transparently. No version bump required — the DB updates silently in the background.
Security: The remote DB is fetched as JSON only — never eval'd or executed. Every entry is validated against a strict schema (pattern allowlist, length caps, confidence enum) before being compiled into RegExp objects. Each regex test is wrapped in try/catch for ReDoS isolation.
| Provider | One-click Allowlist | Blocklist Attribution | Profile Auto-detect | Routing Detection |
|---|---|---|---|---|
| NextDNS | ✅ via REST API | ✅ (HaGeZi, AdGuard, etc.) | ✅ "This device" fingerprint | ✅ test.nextdns.io |
| Pi-hole v5 | ✅ via API Token | — | — | ✅ pi.hole magic domain |
| Pi-hole v6 | ✅ via API Token | ✅ (HaGeZi, OISD, Steven Black, etc.) | — | ✅ pi.hole magic domain |
| Control D | ✅ via API Token | — | ✅ profile picker | ✅ dns.controld.com |
| Any other | 📋 Copy to clipboard | — | — | — |
# Build both Chrome and Firefox (runs tests first)
./build.sh all
# Build for a specific browser
./build.sh chrome
./build.sh firefox
# Remove old artifacts from store/dist/
./build.sh cleanThe build script runs the full test suite before building. If any test fails, the build is aborted. Old version artifacts are automatically cleaned from store/dist/ before each build.
Output goes to store/dist/.
# Run all tests
npm test
# Run specific suites
npm run test:domain # Domain classification (561 entries, 27 categories)
npm run test:errors # Error string detection (24 tests)
npm run test:build # Build artifact validation (41 tests)No dependencies — uses Node's built-in node:test runner. Tests cover:
- Domain classification accuracy across all 27 categories
- Chrome and Firefox error string matching (including curly-apostrophe edge case)
- False-positive rejection (NS_BINDING_ABORTED, ERR_TIMED_OUT, etc.)
extractHostname()edge cases- Manifest schema validation (MV3 and MV2)
- Build artifact existence and size
This extension:
- Does not collect or transmit any personal data
- Does not store browsing history — all data is session-only and cleared on navigation
- Only stores hostnames, never full URLs or page content
- Fetches domain-db.json from GitHub on first load and every 7 days (no user data sent)
- Your NextDNS API key is stored locally in browser sync storage
Full privacy policy: store/PRIVACY.md
- Browser Extension (Chrome MV3 / Firefox MV2)
- Vanilla JS — no build step, no framework dependencies
webRequest.onErrorOccurred— request error monitoringwebNavigation.onCommitted— tab lifecycle managementstorage.local— DB cachingstorage.sync— settings sync across devicesnavigator.clipboard— copy to clipboard- NextDNS REST API — allowlist management
browser-compat.js— cross-browser API shim (chrome.*↔browser.*)db-loader.js— remote DB fetch, validation, and cache management
store/
├── PRIVACY.md # Shared privacy policy
├── chrome/
│ ├── LISTING.md # Chrome Web Store listing copy
│ ├── icon-128-store.png # 128×128 store icon
│ ├── promo-tile-440x280.jpg
│ ├── marquee-1400x560-v2.3.jpg
│ └── screenshots/ # 1280×800 PNG (5 screenshots)
└── firefox/
├── LISTING.md # Firefox Add-ons listing copy
└── screenshots/ # Same screenshots, Firefox-compatible
PRs welcome. Most useful contributions:
- New entries in
domain-db.json— add real hostnames with correct confidence, category, and impact badge - Confidence corrections — if a domain is miscategorized, open a PR with justification
- Impact badge corrections — if the functional impact label is wrong, fix it with reasoning
- Blocklist attribution data — if you know which blocklist targets a domain, add it
- New categories — e.g. identity verification, streaming infrastructure, live events
- Safari iOS port — currently macOS only; iOS needs a content script heuristic approach
- Edge port
- Automated integration tests
When adding entries to domain-db.json, match the schema:
{ "pattern": "exact\\.domain\\.com", "flags": "", "label": "Category (Service Name)", "confidence": "HIGH", "category": "feature-flags" }Run npm test before submitting — the test suite validates every entry and will catch malformed patterns or invalid confidence values.
- Flush banner copy button — visible styled button with "Copied!" confirmation state
- Android flush banner — removed Reload button; shows full plain-English instructions with proper text wrapping
- Firefox for Android support — responsive layout fills the full panel width on mobile
- API key validation — entering a bad key on the → button now shows a red error; nothing is saved
- Cookie bypass fix — all NextDNS API calls now use
credentials: omit; browser session cookies can no longer silently authenticate garbage keys - Android DNS flush — replaced shell command with mobile-friendly instructions and a Reload button
- Popup width — 440px on desktop, fluid on mobile; height grows with content
- Fixed popup icon — replaced hardcoded 🛡️ emoji with the actual extension icon
- Pi-hole blocklist attribution — blocked domains now show which gravity list flagged them (uses
/api/search/{domain}). Pretty-name map for 30+ popular lists: HaGeZi, Steven Black, OISD, AdGuard DNS filter, EasyList/EasyPrivacy, Disconnect.me, Energized, URLhaus, and more. Unknown lists fall back to their hostname. - Previously only available for NextDNS users — now works for Pi-hole v6 too
- Expanded domain database — 492 entries across 13 categories (+146 new entries: CAPTCHA, video players, maps, support chat, image CDNs, error monitoring)
- Functional impact badges — every blocked domain now shows a color-coded badge describing the specific consequence (login, media, maps, chat, features, assets, monitoring, notifications)
- New extension icon — dark shield with cyan medical cross and pulse line
- Pi-hole support — allowlist directly to Pi-hole v5 or v6 (auto-detected)
- NextDNS profile auto-detect — fingerprints your device against your profiles; no manual profile ID needed
- DNS provider toggle — switch between NextDNS and Pi-hole in settings
- Risk-level filter — click HIGH / MEDIUM / LOW stats bar to filter the block list
- DNS flush reminder banner — shows exact OS-aware command after every allowlist/copy action
- DNS flush banner after allowlist actions
- Copy to clipboard button
- Remote domain database with 7-day cache and force-refresh
- Firefox support (MV2)
- Dynamic remote domain database
If DNS Medic saved you a headache, buy me a coffee ☕ — it's appreciated but never expected.
MIT
This application was built with the help of AI.
