Forward Email
forwardemail.netCatch-all email forwarding service with unlimited aliases and custom domains, configured via DNS records. Self-hostable; the hosted version has a limited free plan, with paid plans (from $3/month) adding encrypted IMAP/POP3 mailboxes. Audited by Cure53 in 2026.
- Homepage: forwardemail.net
- GitHub: github.com/forwardemail/forwardemail.net
- Subreddit: r/forwardemail
- Web info: web-check.xyz/check/forwardemail.net
Forward Email Source Code
Author
Description
Privacy-focused encrypted email for everyone. All-in-one alternative to Gmail + Mailchimp + Sendgrid.
Homepage
https://forwardemail.netLicense
NOASSERTION
Created
17 Dec 19
Last Updated
04 Jul 26
Latest version
Primary Language
JavaScript
Size
1,063,742 KB
Stars
1,612
Forks
199
Watchers
1,612
Language Usage
Star History
Top Contributors
-
@titanism (3626)
-
@niftylettuce (745)
-
@shaunwarman (194)
-
@shadowgate15 (99)
-
@spence-s (31)
-
@178inaba (5)
-
@homburg (4)
-
@cbertelli (3)
-
@basic70 (3)
-
@olearycrew (2)
-
@jamescridland (2)
-
@alicegomaird (2)
-
@slaweally (1)
-
@BastelPichi (1)
-
@brian6932 (1)
-
@chrnie (1)
-
@Melendeze13 (1)
-
@fbartels (1)
-
@flaviomartins (1)
-
@IzumiSenaSora (1)
-
@junxit (1)
-
@Lordfirespeed (1)
-
@wonderlandpark (1)
-
@thorpelawrence (1)
-
@Maxr1998 (1)
-
@benders (1)
-
@robertscholts (1)
-
@SergioChan (1)
-
@5idereal (1)
-
@c0dr (1)
-
@sgraaf (1)
-
@buzali (1)
-
@andylizi (1)
-
@ceonelson (1)
-
@C0reFast (1)
-
@clouedoc (1)
-
@samshadwell (1)
-
@snyk-bot (1)
-
@aoaoho (1)
-
@hyunbridge (1)
Recent Commits
-
titanism (04 Jul 26)
test: update macOS frozen version test expectations Tests now expect the corrected macOS version (26.5/26.0) from the Version/ token instead of the frozen 10.15.7 value.
-
titanism (04 Jul 26)
fix: strip angle brackets from recipient in DSN text (#537) The failed email address was enclosed in <> in the human-readable text/plain part of delivery status notifications. Email clients that render text as HTML interpret this as a tag, hiding the address. Remove the angle brackets so the recipient displays correctly. Closes #537
-
titanism (04 Jul 26)
fix: correct frozen macOS version in session display macOS version is frozen at 10.15.7 in the UA string since Big Sur. Use the Safari Version/ token to infer the real macOS version when the reported version is the known frozen value.
-
titanism (04 Jul 26)
fix: exclude admin impersonation sessions from user session list When an admin uses "Log in as user", mark the session with _admin_impersonation flag. Skip session tracking in the middleware and filter it out in list-user-sessions so the impersonated user never sees the admin's session in their Session Management UI.
-
titanism (04 Jul 26)
refactor: replace custom UA parser with [email protected] - Use ua-parser-js with Emails extension for Thunderbird detection - Library handles frozen iOS 26 UA automatically - Add 19 comprehensive tests for parseUA
-
titanism (04 Jul 26)
2.9.6
-
titanism (04 Jul 26)
fix: iOS version detection for frozen UA strings (iOS 26+) Apple froze the OS version in the UA string starting with iOS 26 (reports "iPhone OS 18_6" even on iOS 26+). Use the Safari Version/ token to infer the real iOS version when its major exceeds the reported OS major. Also adds CriOS and FxiOS browser detection.
-
titanism (04 Jul 26)
2.9.5
-
titanism (04 Jul 26)
feat: default forwarding address; fix: iOS detection, session refresh, timeout logs 1. Default Forwarding Address profile setting: - New field on User model with same validation as alias recipients - Falls back to user.email when not set - Integrated in alias validation, domain creation, billing, import 2. iOS/iPadOS UA detection: - Reorder OS checks so iPad/iPhone match before generic Mac - Use Mobile token heuristic for iPhone vs iPad distinction 3. Session IP/UA refresh on every authenticated request 4. Timeout log suppression: - Filter logs with specific timeout message text across list-logs, retrieve-log, list-analytics, and daily-log-alert
-
titanism (04 Jul 26)
2.9.4
-
titanism (04 Jul 26)
fix: DMARC chart label, folder counts, DNS false-positive alerts, session management fix(dmarc): use dynamic series sum for donut chart center label The center label used a pre-computed totalLabel from stats.total_messages which could show 0 even when alignment data exists. Now sums the actual series values from ApexCharts globals so the center always matches. fix(folders): return total and unseen_count in GET /v1/folders response The webmail client fell back to counting locally cached messages when the API returned no message counts, causing incorrect and inconsistent folder totals. Now calls Messages.countDocuments() per folder. fix(dns): treat Redis/timeout errors as transient in all hasDNSError checks The hasDNSError check only matched err.code against DNS_RETRY_CODES, but ioredis MaxRetriesPerRequestError has no .code property. This caused false-positive "DNS configuration issue" emails when the resolver's Redis cache timed out. Added isTimeoutError() alongside DNS_RETRY_CODES in all 8 affected files. feat(sessions): per-session listing with device, IP, last active and revocation Added session metadata tracking (IP, user-agent, timestamps) to Redis sessions, a helper to list/parse sessions, a revoke-session route, and a detailed sessions table in the security view. fix(analytics): remove "none" from log category filter feat(dmarc): add FAQ link to reports page and weekly email
-
titanism (02 Jul 26)
fix: bump koa
-
titanism (02 Jul 26)
2.9.3
-
titanism (02 Jul 26)
fix: replace optional chaining in dmarc-reports.js for browserify compatibility Browserify 17's acorn parser does not support optional chaining (?.) syntax. Use explicit property checks instead.
-
titanism (02 Jul 26)
2.9.2
-
titanism (02 Jul 26)
fix(security): strip inbound headers carrying own authserv-id (RFC 8601 ยง5) On ingress, remove any Authentication-Results or ARC-Authentication-Results header whose authserv-id matches our own hostname or any *.forwardemail.net subdomain before running authentication checks. This prevents an unauthenticated sender from injecting a spoofed dmarc=pass verdict under our authserv-id that could mislead downstream Sieve filters or client-side rules. Also rewrites the DMARC FAQ section and adds translations to all 24 locales.
-
titanism (02 Jul 26)
fix: omit apns-priority header for Mail push and fix DMARC donut chart showing incorrect count APNs (send-apn.js): - Set note.priority = undefined for Mail pushes so node-apn omits the apns-priority header entirely, matching dovecot-xaps-daemon's wire format. Explicitly sending apns-priority (10 or 5) alongside apns-push-type: background causes iOS to silently ignore the push. - Calendar/Contact pushes retain priority 5 (true background pushes). DMARC Reports (list-dmarc-reports.js, assets/js/dmarc-reports.js): - Replace the donut chart formatter arrow function with a pre-computed totalLabel string field. The function was silently stripped by JSON.stringify during response serialization, causing ApexCharts to fall back to summing the placeholder series [1,1] = "2" instead of displaying "0". - Client-side code now reads totalLabel and constructs the formatter function before passing options to ApexCharts.
-
titanism (30 Jun 26)
fix: omit apns-priority header for Mail pushes to enable immediate delivery All known working XAPPLEPUSHSERVICE implementations (dovecot-xaps-daemon, courier-apns, Apple's own macOS Server pushnotify) send Mail push notifications without an explicit low-priority header, causing Apple to default to priority 10 (immediate delivery). We were explicitly setting note.priority = 5, which tells Apple to deliver "based on power considerations" -- meaning iOS may batch and delay the notification indefinitely. This caused users to only receive new-mail notifications at fetch intervals rather than in real time. The fix only sets priority 5 for Calendar/Contact pushes (where batched delivery is acceptable) and leaves Mail pushes at the node-apn default of 10, matching the dovecot-xaps-daemon reference implementation which explicitly comments out PriorityLow: https://github.com/freswa/dovecot-xaps-daemon/blob/main/internal/apns.go#L162-L163 Additionally fixes a stale comment in debug-apns.js that incorrectly referenced pushType=alert for Mail (it is background ).
-
shaunwarman (28 Jun 26)
docs(faq): clarify DMARC report failures are impersonation attempts
-
titanism (27 Jun 26)
2.9.1
-
titanism (27 Jun 26)
fix: improve search accuracy, exclude landing pages, add delete account FAQ, restore logoutBeforeReset - app/controllers/web/search.js: add phrase-match boosting and re-ranking so exact multi-word queries (e.g. "delete account") surface the most relevant FAQ/help sections first. Fetch 50 candidates from MongoDB text search, boost by exact phrase presence in header/title/content, then trim to top 25. Use .lean() for performance. - jobs/crawl-sitemap.js: exclude programmatic use-case pages, individual alternative pages, pairwise comparison pages, comparison landing pages, and open-source platform pages from the internal search index. These thin/SEO pages dilute search results with repetitive content. Pages are still crawled for HTTP cache warming and OG image generation. Stale entries for excluded pages are cleaned up via deleteMany on each run. - app/views/faq/index.md + all 24 locale variants: add "How do I delete my account?" FAQ section (placed before the money-back guarantee section) with step-by-step instructions for account deletion via My Account > Security. Translated into ar, cs, da, de, es, fi, fr, he, hu, id, it, ja, ko, nl, no, pl, pt, ru, sv, th, tr, uk, vi, zh. - app/controllers/web/auth.js: restore logoutBeforeReset middleware that was accidentally removed. Routes still reference it for /reset-password routes causing undefined middleware crash on startup.
-
titanism (25 Jun 26)
fix: GET querystring fallback, Buffer flags crash, admin controller and auth fixes - helpers/get-mongo-query.js: fall back to ctx.query.mongodb_query when ctx.request.body is empty so pagination links, sort headers, and Quick filter buttons work on GET requests (fixes Admin > Logs, Emails, etc.) - helpers/imap/on-store.js: harden getFlag() to coerce non-string flag elements (Buffer) to strings before calling .trim(). - helpers/imap/on-move.js: normalize decoded flags array to strings after decodeMetadata(); use Set with .has() for Deleted/Seen checks. - helpers/get-query-response.js: filter non-string elements from message.flags in the else branch (no labels). - app/controllers/web/admin/{domains,inquiries,payments,users}.js, app/controllers/web/auth.js, emails/inquiry/html.pug, routes/api/v1/index.js, routes/web/otp.js: restore fixes from previously reverted commit.
-
titanism (25 Jun 26)
Revert "fix(sqlite): make close-on-evict concurrency-safe and restore lax cadence" This reverts commit 2853f53308b90e8b4fb58d695f8048a313ccdf24.
-
titanism (25 Jun 26)
Revert "fix: GET querystring fallback, Buffer flags crash, and SQLite worker affinity routing" This reverts commit fbc71a081d3a28aece16d10a8202eba7c18986fd.
-
titanism (25 Jun 26)
Revert "fix: health-aware SQLite worker affinity routing" This reverts commit 8f30a8c1ca2ed4fe46eccc0d97e39dc1c6daf42f.
-
titanism (25 Jun 26)
fix: health-aware SQLite worker affinity routing Implement per-worker health tracking with bounded fallback in getWorkerForAlias(). Workers are marked unhealthy after UNHEALTHY_THRESHOLD (3) consecutive close events without a successful open (~16.5s of sustained unreachability). Unhealthy targets trigger fallback to a healthy open worker, preserving affinity for transient reconnections while avoiding indefinite blocking when a worker's event loop is saturated (e.g. during VACUUM or heavy queries). Workers auto-recover on successful open. Verbose routing logs gated behind SQLITE_VERBOSE_ROUTING.
-
titanism (25 Jun 26)
fix: GET querystring fallback, Buffer flags crash, and SQLite worker affinity routing - helpers/get-mongo-query.js: fall back to ctx.query.mongodb_query when ctx.request.body is empty so pagination links, sort headers, Quick filter buttons, and cross-links (?mongodb_query=...) work on GET requests. Fixes Admin > Logs, Admin > Emails, and any route using getMongoQuery(). - helpers/imap/on-store.js: harden getFlag() to coerce non-string flag elements (Buffer) to strings before calling .trim(). - helpers/imap/on-move.js: normalize decoded flags array to strings after decodeMetadata(); use Set with .has() for Deleted/Seen checks. - helpers/get-query-response.js: filter non-string elements from message.flags in the else branch (no labels). - helpers/create-websocket-as-promised.js: always prefer the affinity target in getWorkerForAlias() when its ReconnectingWebSocket is willing to reconnect (_shouldReconnect !== false). The 500ms-3s reconnection window is transient; sendRequest() already waits up to 15s via pWaitFor. Only fall back when a worker is permanently closed. Gate verbose routing logs behind SQLITE_VERBOSE_ROUTING; downgrade fallback logs to logger.warn/logger.debug.
-
titanism (23 Jun 26)
2.9.0
-
titanism (23 Jun 26)
fix: admin dashboard stats, duplicate paypal payments, password reset, DMARC bypass, websocket error leak, and storage quota propagation - fix(web): replace ensureLoggedOut with logoutBeforeReset on /reset-password/:token routes so authenticated users are transparently logged out instead of silently redirected away; remove unnecessary confirm-prompt from the reset form - fix(admin): use refunded_at instead of updated_at in getRefunds() to prevent background sync jobs from inflating refund totals; add refunded_at field to Payment model and set it in refund helper and sync helpers - fix(paypal): add unique sparse index on paypal_order_id and wrap Payments.create in both webhook and redirect handlers with try/catch for E11000 duplicate key errors to prevent race condition between processEvent and retrieveDomainBilling - fix(admin): replace hardcoded upgrade/downgrade estimates with actual MongoDB $lookup aggregations; cap Quick Ratio at 10 instead of 999 when churn is zero - fix(smtp): restrict DSN exemption to actual bounce usernames (mailer-daemon, postmaster, bounce) instead of the full POSTMASTER_USERNAMES set; require 2-of-3 structural indicators; require allowlistValue/resolvedRootClientHostname to match the From header root domain; reject when From domain matches a recipient domain - fix(smtp): sanitize internal WebSocket/SQLite timeout error messages in refineAndLogError and the imap() catch block so users see a generic retry message instead of raw RequestId and infrastructure details - fix(admin): when admin increases user max_quota_per_alias, propagate the new limit to all domains/aliases that were set to the exact previous limit; also fix ctx.state.user._id bug (was clearing cache for admin instead of target user) - style: replace Array.reduce with for loop (unicorn/no-array-reduce); apply xo --fix formatting corrections - scripts: add backfill-refunded-at.js migration that fetches actual refund timestamps from Stripe and PayPal APIs (with --dry-run support)
-
titanism (23 Jun 26)
fix: launchpad ipv4, per-alias wkd opt-out, event-feed multi-repo, rtl arrows - fix(launchpad): switch address family from IPv6 to IPv4 IPv6 TLS handshake to api.launchpad.net hangs; IPv4 succeeds reliably. - feat(aliases): per-alias WKD opt-out (closes #532) Adds has_wkd_disabled boolean (default false) to Aliases model. When enabled, WKD lookup is skipped during inbound forwarding. Includes: model field, API spec + all translated variants, FAQ updates (all languages), UI toggle, validation, API/web controllers, forwarding pipeline plumbing, and 5 new E2E tests. Updates test/api/v1.js expected response keys. - feat(event-feed): include releases from mail.forwardemail.net get-github-releases.js now fetches from both forwardemail/forwardemail.net and forwardemail/mail.forwardemail.net, merging results by date. Affects /event-feed page, ICS calendar, and RSS/Atom feeds. - fix(rtl): mirror directional arrows for RTL languages (closes #396) Adds CSS rules to _custom.scss that flip fa-angle-right, fa-angle-double-right, fa-arrow-right, fa-chevron-right, fa-long-arrow-right (and left counterparts) when dir=rtl.
Forward Email Website
Website
Free Email Forwarding for Custom Domains - #1 Open Source Email Service 2026
Get free email forwarding for custom domains. Send & receive as [email protected] with unlimited aliases, 10GB storage, IMAP/POP3/SMTP & 100% open-source security. Trusted by 500K+ users. Setup in 2 minutes.
Redirects
Redirects to https://forwardemail.net/000+
Security Checks
1 security checks failed (64 passed)
- Password Field Present
Server Details
- IP Address 121.127.44.69
- Hostname forwardemail.net
- Location Denver, Colorado, United States of America, NA
- ISP DataCamp Limited
- ASN AS60068
Associated Countries
-
US
Safety Score
Website marked as moderately safe
90%
Blacklist Check
forwardemail.net was found on 0 blacklists
- AntiSocial Blacklist
- Artists Against 419
- Badbitcoin
- Bambenek Consulting
- CERT Polska
- CoinBlockerLists
- CRDF
- CryptoScamDB
- EtherAddressLookup
- EtherScamDB
- Fake Website Buster
- MetaMask EthPhishing
- NABP Not Recommended Sites
- OpenPhish
- PetScams
- PhishFeed
- PhishFort
- Phishing.Database
- PhishStats
- PhishTank
- Phishunt
- RPiList Not Serious
- Scam.Directory
- SecureReload Phishing List
- Spam404
- StopGunScams
- Suspicious Hosting IP
- ThreatFox
- ThreatLog
- TweetFeed
- URLhaus
- ViriBack C2 Tracker
Website Preview
Forward Email Reviews
More Mail Forwarding
-
A long-standing aliasing service. As well as receiving, 33Mail also lets you reply to forwarded addresses anonymously. Free plan, as well as Premium plan ($1/ month) if you'd like to use a custom domain. Note that 33Mail usese Google Analytics.
Not Open Source -
An open source anonymous email forwarding service, allowing you to create unlimited email aliases. Has a free plan.
-
Developed and managed by Mozilla, Relay is a Firefox addon, that lets you make an email alias with 1 click, and have all messages forwarded onto your personal email. Relay is totally free to use, and very accessible to less experienced users, but also open source, and able to me self-hosted for advanced usage.
-
If you already have ProtonMail's Professional (โฌ8/month) or Visionary (โฌ30/month) package, then an implementation of this feature is available via the Catch-All Email feature.
-
Fully open source (view on GitHub) alias service with many additional features. Can be self-hosted, or the managed version has a free plan, as well as hosted premium option ($2.99/ month) for using custom domains.
About the Data: Forward Email
Change History
- Moved from Communication โบ Encrypted Email #660
API
You can access Forward Email's data programmatically via our API. Simply make a GET request to:
https://api.awesome-privacy.xyz/v1/services/forward-email The REST API is free, no-auth and CORS-enabled. To learn more, view the API Docs or read the API Usage Guide.
Share Forward Email
Help your friends compare Mail Forwarding, and pick
privacy-respecting software and services.
Share Forward Email and Awesome Privacy with your network!