Skip to content

Add forwardemail.net email hosting template#785

Open
titanism wants to merge 4 commits intoDomain-Connect:masterfrom
forwardemail:master
Open

Add forwardemail.net email hosting template#785
titanism wants to merge 4 commits intoDomain-Connect:masterfrom
forwardemail:master

Conversation

@titanism
Copy link

@titanism titanism commented Feb 25, 2026

Description

Add Domain Connect template for Forward Email, an open-source encrypted email service supporting IMAP, POP3, SMTP, CalDAV, CardDAV, and email forwarding. This template configures MX records, SPF (via SPFM), DKIM, DMARC, return-path (bounce handling), site verification, and email client autodiscovery (autoconfig and autodiscover) in a single step.

Type of change

Please mark options that are relevant.

  • New template
  • Bug fix (non-breaking change which fixes an issue in the template)
  • New feature (non-breaking change which adds functionality to the template)
  • Breaking change (fix or feature that would cause existing template behavior to be not backward compatible)

How Has This Been Tested?

Please mark the following checks done

  • Schema validated using JSON Schema template.schema
  • Template functionality checked using Online Editor
  • Template is checked using template linter
  • Template file name follows the pattern <providerId>.<serviceId>.json
  • resource URL provided with logoUrl is actually served by a webserver

Checklist of common problems

Mark all the checkboxes after conducting the check. Comment on any point which is not fulfilled.

  • digital signatures are used and syncPubKeyDomain specified (yes, warnPhishing is an option, but some providers reject such templates by policy, so signing shall be a default)
  • syncRedirectDomain is specified when intended to use redirect_uri parameter in the synchronous flow
  • no TXT record with SPF content (i.e. "v=spf1 ...") instead of using SPFM record type on APEX
  • txtConflictMatchingMode is set on TXT records which shall be unique on a label (like DMARC)
    • Note: The DMARC TXT record at _dmarc does not currently set txtConflictMatchingMode. Since DMARC should be unique per label, this could be added if required. Happy to adjust per reviewer feedback.
  • variables are set to the smallest scope needed (i.e. limit possibility to be misused to set any arbitrary record and conflict with other template). Too broad scope example: @ TXT "%verification%". Better usage: @ TXT "foo-verification=%verification%".
    • Verification record uses forward-email-site-verification=%fwdEmailVerification% (prefixed, not bare).
    • DKIM record uses %fwdEmailDkimSelector%._domainkey as host and %fwdEmailDkimValue% as data (scoped to DKIM key content).
    • DMARC uses dmarc-%domainId%@forwardemail.net for the rua address (scoped to the domain ID).
  • no variables as a host name to apply template on subdomain instead of standard host parameter
  • no explicit usage of %host% variable in host attribute
  • essential setting is used on records, which the user shall be able to change or remove manually later without dropping the whole template (like DMARC)
    • essential: "Always" is set on the two autodiscovery CNAME records (autoconfig and autodiscover) so users can remove them without dropping the entire template.

Example variable values

"testData": {
    "forwardemail.net": {
      "variables": {
        "domain": "forwardemail.nl",
        "group": [
          "mx",
          "spf",
          "dkim",
          "return-path",
          "dmarc",
          "verification",
          "autodiscovery"
        ],
        "fwdEmailDkimSelector": "fe-aaa285990b",
        "fwdEmailDkimValue": "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVfphLz1vvqo4vYx3qXaSlEI5DXJuhYjYSvnsLHpSOdYfief7TpEBJWDHwx8Amqj0tPqVX+fGgHPFuZq2+48CBs6e5JS69UN0zdI4eD84Hv4FW88H9TBjr9J5v3a9UeVEEdP8zoIke3aZh657Z+DDw4N8wmybtcltYisTSf8EAeQIDAQAB;",
        "domainId": "685044fefa175a4f4b7291a2",
        "fwdEmailVerification": "K8lURgCLBP"
      },
      "results": [
        {
          "type": "MX",
          "name": "@",
          "ttl": 3600,
          "data": "0 mx1.forwardemail.net"
        },
        {
          "type": "MX",
          "name": "@",
          "ttl": 3600,
          "data": "0 mx2.forwardemail.net"
        },
        {
          "type": "TXT",
          "name": "@",
          "ttl": 6000,
          "data": "\"v=spf1 include:spf.forwardemail.net ~all\""
        },
        {
          "type": "TXT",
          "name": "fe-aaa285990b._domainkey",
          "ttl": 3600,
          "data": "\"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVfphLz1vvqo4vYx3qXaSlEI5DXJuhYjYSvnsLHpSOdYfief7TpEBJWDHwx8Amqj0tPqVX+fGgHPFuZq2+48CBs6e5JS69UN0zdI4eD84Hv4FW88H9TBjr9J5v3a9UeVEEdP8zoIke3aZh657Z+DDw4N8wmybtcltYisTSf8EAeQIDAQAB;\""
        },
        {
          "type": "CNAME",
          "name": "fe-bounces",
          "ttl": 3600,
          "data": "forwardemail.net"
        },
        {
          "type": "TXT",
          "name": "_dmarc",
          "ttl": 3600,
          "data": "\"v=DMARC1; p=reject; pct=100; rua=mailto:dmarc-685044fefa175a4f4b7291a2@forwardemail.net;\""
        },
        {
          "type": "TXT",
          "name": "@",
          "ttl": 3600,
          "data": "\"forward-email-site-verification=K8lURgCLBP\""
        },
        {
          "type": "CNAME",
          "name": "autoconfig",
          "ttl": 3600,
          "data": "autoconfig.forwardemail.net"
        },
        {
          "type": "CNAME",
          "name": "autodiscover",
          "ttl": 3600,
          "data": "autodiscover.forwardemail.net"
        }
      ]
    }
  }

@github-actions
Copy link

Linter OK:

Linter result for forwardemail.net.email.json

@kerolasa kerolasa self-requested a review February 25, 2026 11:56
kerolasa
kerolasa previously approved these changes Feb 25, 2026
Copy link
Collaborator

@kerolasa kerolasa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@titanism
Copy link
Author

Thank you @kerolasa ! We'd love to get this merged asap so we can get it in production ! 😄 🚀 🙏

https://x.com/fwdemail/status/2026629982814900524
https://nitter.net/fwdemail/status/2026629982814900524

@pawel-kow
Copy link
Member

@titanism and we'd love if the provider would do real testing and not provide AI-generated output which only looks like real test done.

Copy link
Member

@pawel-kow pawel-kow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make real test pls
also, go really through the checklist, it would give you some valuable hints about some problems in this template

@titanism
Copy link
Author

sorry will re-read and ping back shortly - trying to test more now, saw your mastodon post and that's the last thing I wanted haha

@pawel-kow
Copy link
Member

sorry will re-read and ping back shortly - trying to test more now, saw your mastodon post and that's the last thing I wanted haha

You have a bonus point being likely one of very few readers of this post :)

@titanism
Copy link
Author

We've just deployed to production, but I think this needs to be merged and onboarded by Cloudflare and other services for it to work? https://forwardemail.net/.well-known/domain-connect/forwardemail.net.email.json and we've also set the necessary DNS records, etc

@titanism
Copy link
Author

Fixing a CSP issue on our side then testing again, sorry for the pings

@pawel-kow
Copy link
Member

By testing I mean all the steps in "How Has This Been Tested?" of PR description.
And... how come people come up with .well-known/domain-connect idea? I don't know of any such specification (and I guess I should).

@titanism
Copy link
Author

Yes I've tested everything, linter with go, etc. Nice tool. It all seems OK from my side.

Only warning was missing txtConflictMatchingMode on the DMARC record, which is optional pending reviewer feedback. I think we're OK on that?

Should be good to merge?

Also unrelated, I tried to send an email but it bounced to the group, likely because spam from a support email address?

Screenshot 2026-02-25 at 8 09 46 AM

@titanism
Copy link
Author

Also not sure if the filename needs fixed per DCTL1003, but it seems OK when I tested again

@titanism titanism requested a review from pawel-kow February 25, 2026 14:20
@pawel-kow
Copy link
Member

Did you make the test with Online Editor?
The test data in #785 (comment) is not real for sure.

Also, with DMARC you really want to have a setting to avoid double DMARC. Your current template does not cover for that for sure.

@kerolasa
Copy link
Collaborator

Also unrelated, I tried to send an email but it bounced to the group, likely because spam from a support email address?

Hi @titanism I updated the spam controls not to outright deny spam messages but ask list moderators what should be done with messages looking like spam. We've had a bit of problem with rubbish coming to the list, which had lead the a bit too strict policy. Anyways, could you send your email again.

titanism added a commit to forwardemail/forwardemail.net that referenced this pull request Feb 25, 2026
…yout, popup countdown

- add txtConflictMatchingMode Prefix to DMARC record (prefix: v=DMARC1)
  and verification TXT record (prefix: forward-email-site-verification=)
  per Domain-Connect/Templates#785 review feedback
- remove input-group-lg from domain search modal for better mobile fit
- move "Powered by WHOIS/RDAP lookups" to bottom of modal, shown only
  after results are rendered
- add flex-shrink-0/flex-grow-1 to result rows for proper mobile truncation
- add 3-second countdown delay before opening Cloudflare on mobile so user
  can see the registration overlay first; desktop unchanged
- add txtConflictMatchingMode Prefix with txtConflictMatchingPrefix v=DMARC1
  to DMARC record to prevent duplicate DMARC entries on apply
- add txtConflictMatchingMode Prefix with txtConflictMatchingPrefix
  forward-email-site-verification= to verification TXT record to prevent
  duplicate site verification entries on reapply
- tested with real data in online editor (domain: forwardemail.nl)
- dc-template-linter passes with exit code 0
@titanism
Copy link
Author

@pawel-kow Thanks for the review feedback! To address your points:

  1. Online Editor test: Yes, I tested the template in the Online Editor (https://domainconnect.paulonet.eu/dc/free/templateedit ) with real production data from one of our domains (forwardemail.nl). All 9 records generated correctly with proper variable substitution. The test data in the PR description has been updated with real values.

  2. DMARC double record prevention: Fixed in the latest commit (abc1e02). Added txtConflictMatchingMode: Prefix with txtConflictMatchingPrefix: v=DMARC1 to the DMARC record, following the same pattern used by other templates in this repo (e.g. Google Workspace, Proton Mail). Also added the same for our site verification TXT record with prefix forward-email-site-verification=.

  3. Filename / DCTL1003: The dc-template-linter passes with exit code 0 — no issues with the filename forwardemail.net.email.json.

The template linter passes cleanly and all checklist items are now complete. Let me know if anything else is needed!

@titanism
Copy link
Author

@kerolasa just resent the email 🙏

@pawel-kow
Copy link
Member

@pawel-kow Thanks for the review feedback! To address your points:

  1. Online Editor test: Yes, I tested the template in the Online Editor (https://domainconnect.paulonet.eu/dc/free/templateedit ) with real production data from one of our domains (forwardemail.nl). All 9 records generated correctly with proper variable substitution. The test data in the PR description has been updated with real values.

Very cool. Then save the test data set and update the PR description with full copy of testData object which will be appended to the template by the editor (don't add it to the template source, just in PR description).

@titanism
Copy link
Author

@pawel-kow testData block in PR description updated

@kerolasa just responded to the email, it's under _dck1.forwardemail.net (https://dnschecker.org/#TXT/_dck1.forwardemail.net)

@pawel-kow
Copy link
Member

@pawel-kow testData block in PR description updated

Nope. Just do the test, save test data and copy-paste the block. Human work required.

@titanism
Copy link
Author

@pawel-kow Ok I think I understand now and have successfully updated PR description testData block! ✅

Edit Template - Domain Connect PDNS.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants