Skip to content

Before You Install

chrisholloway5 edited this page Sep 8, 2026 · 2 revisions

Before You Install

This page began as a chapter of the 6.2.10 manual and has been corrected against the 6.2.28 source tree. The Control Panel's pages are grouped differently now, so the paths below use today's groups; the TLS ports 465, 993 and 995 exist only after you create them on the TCP/IP ports page (a fresh install seeds 25, 587, 110 and 143); and everything added since 6.2.10 is in Changes-Since-6210. Where a value here disagrees with the Settings Reference, which is generated from the code, the reference is right.

Work through this before you download anything. Skipping it is the usual cause of a painful first day.

Five minutes with this flowchart will tell you whether the machine in front of you can be a mail server at all, or whether you are heading for the smart-host arrangement in Routes and Relays instead.

flowchart TD
    A["64-bit Windows 10 1607 / Server 2016 or newer?"] -->|No| STOP1["Setup refuses to run. MinVersion=10.0.14393"]
    A -->|Yes| B["Do you control the domain's DNS?"]
    B -->|No| STOP2["Get DNS access first. MX, SPF, DKIM and DMARC all live there"]
    B -->|Yes| C["Static public IP?"]
    C -->|No| WARN1["Workable but fragile. Dynamic IPs are widely blacklisted"]
    C -->|Yes| D["Inbound TCP 25 reaches this machine?"]
    WARN1 --> D
    D -->|No| E["Relay-only installation: you can send through a smart host but cannot receive directly"]
    D -->|Yes| F["Outbound TCP 25 permitted?"]
    F -->|No| E
    F -->|Yes| G["PTR record requested from your provider?"]
    G -->|No| WARN2["Install anyway, but chase it. Google and Microsoft refuse mail from IPs with no matching PTR"]
    G -->|Yes| H["Choose a database"]
    WARN2 --> H
    E --> H
    H --> I["Ready to install"]
Loading

3.1 A Windows machine

The hard floor is enforced by the installer, not by advice. section_setup.iss sets MinVersion=10.0.14393 and section_setup_64.iss sets ArchitecturesAllowed=x64, so on anything older, or on 32-bit Windows, setup stops with the message from section_messages.iss:

hMailServer requires Windows 10 version 1607 (build 14393) / Windows Server 2016
or later, 64-bit.
Requirement Value Where it comes from What happens when it is wrong
Windows version 10.0.14393 or newer installation/section_setup.iss, MinVersion Setup refuses to start. The floor is the .NET 10 Desktop Runtime's own floor, and that runtime is what the database tools need
Architecture x64 only installation/section_setup_64.iss, ArchitecturesAllowed=x64 Setup refuses to start
Elevation Administrator section_setup.iss, PrivilegesRequired=admin Setup will not proceed: it creates a Windows service and writes to HKLM
.NET 10 Desktop Runtime Installed automatically when missing bundled windowsdesktop-runtime-10.0-win-x64.exe, section_files_64.iss Without it DBSetup, DBSetupQuick and DBUpdater cannot run, so the database is never created and the service starts against nothing
Visual C++ runtime Shipped app-local (v145) Microsoft.VC145.CRT\* copied into {app}\Bin Nothing to install — but never replace those DLLs with older ones; the service crashes on startup
RAM 2 GB minimum, more for a busy server operational guidance Thrashing under load. Nothing enforces it
Uptime Always on operational reality A mail server that is asleep is a mail server that is losing mail

Disk. Size for how much mail you will keep, not how much you have today. Two settings decide what the server does when the disk fills, and both are enforced during the SMTP conversation rather than at delivery time:

Setting Default Effect
MinimumFreeDiskSpaceMB 100 Below this, MAIL FROM is answered 452 4.3.1 — a temporary refusal, so the sending server holds the message and retries. No spool file is opened and no recipient is validated
DiskSpaceWarningThresholdMB 1024 Above the floor but below this, the server logs a warning and keeps accepting mail

(IniFileSettings.cpp:522-525; both are also in the Settings Reference.)

The mail itself lands under the data directory, one file per message:

C:\Program Files\hMailServer\
├── Bin\            hMailServer.exe, the .NET tools, OpenSSL, libpq, libmysql, hMailServer.INI
├── Data\           ← MESSAGES LIVE HERE. Size the disk for this folder
│   ├── example.com\
│   │   └── alice\
│   │       └── 3f\{3f7c....eml}   two-character fan-out folder, then a GUID-named .eml
│   ├── #Public\    public folders, same two-character fan-out
│   └── {guid}.eml  messages still in the delivery queue
├── Database\       the built-in database file, hMailServer.sdf
├── DBScripts\      the .sql create and upgrade scripts
├── Events\         EventHandlers.vbs — preserved across upgrades
├── Languages\      Control Panel translations
├── Logs\           hmailserver_*.log
├── Temp\
├── Addons\         DataDirectorySynchronizer, ImportTool
├── ControlPanel\   hMailCP.exe and its .NET dependencies
└── WebAdmin\       the single-page admin app served by the REST listener

(Folder set from installation/section_dirs.iss; message path shape from PersistentMessage::GetFileName, Common/Persistence/PersistentMessage.cpp:1510-1545.)

Antivirus. Exclude Data\, Database\ and Temp\ from real-time scanning. A scanner holding a message file open is a documented cause of delivery that silently does nothing — the server detects one shape of it explicitly and logs error 5760 rather than writing a message with no body (DistributionListSender::LoadedMessageIsGenuine_).

3.2 A domain name

You need a domain you control — yourcompany.com — and the ability to edit its DNS records. If your domain is with a registrar like Namecheap, Cloudflare, GoDaddy or 123-Reg, you have this.

You will need to publish, at minimum, an MX record and an SPF TXT record, and you should publish DKIM and DMARC too. The Control Panel generates the exact record text for each of them and then checks whether it is live: Monitoring & troubleshooting → DNS records. You cannot do that until the server is installed, but it is worth knowing now that you will not have to compose those records by hand. See DNS for Your Domain.

3.3 A static public IP address — and port 25 open

This is the step that stops most home installations.

  • Your server needs a static public IP. A dynamic home IP will work badly and be widely blacklisted.
  • Port 25 inbound must reach your server. Most consumer ISPs block it. Business connections and cloud/VPS providers usually allow it, sometimes on request.
  • Port 25 outbound must work too. Many cloud providers (notably Azure and AWS) block outbound 25 by default and require you to ask.

Test both directions before you install — the second one from the server itself, the first from anywhere else:

# Inbound: can the outside world reach port 25 on your IP?
Test-NetConnection -ComputerName 203.0.113.10 -Port 25

# Outbound: can this machine reach someone else's port 25?
Test-NetConnection -ComputerName gmail-smtp-in.l.google.com -Port 25
ComputerName     : gmail-smtp-in.l.google.com
RemoteAddress    : 142.250.153.26
RemotePort       : 25
TcpTestSucceeded : True

TcpTestSucceeded : False on the outbound test means port 25 is blocked and you need a smart host.

The ports you will eventually need open:

Port Protocol Seeded by a fresh install? Needed for
25 SMTP Yes Receiving mail from other servers. Without it you receive nothing
587 SMTP submission Yes Your own users sending mail
110 POP3 Yes Legacy clients
143 IMAP Yes Mail clients reading mail
465 SMTPS, implicit TLS No — create it yourself Clients that will not use STARTTLS
993 IMAPS, implicit TLS No — create it yourself The port most mail clients try first
995 POP3S, implicit TLS No — create it yourself Legacy clients over TLS

The four seeded rows come from CreateTablesMSSQL.sql:1054-1060; the TLS ports are added on Connections & protocols → TCP/IP ports. Full detail in Ports Reference.

Check before you commit. If your ISP blocks port 25, you cannot receive mail directly. You can still run hMailServer and relay outbound mail through a smart host (Routes and Relays), but inbound mail will not reach you.

Setup itself checks three of these ports. InitializeSetup calls CheckPorts() from the bundled ISC.DLL and, when 25, 110 or 143 are already listening while the hMailServer service is not running, tells you another mail server is on the machine. It is a warning, not a refusal — but ignore it and two servers will fight over port 25.

3.4 Reverse DNS (PTR)

Your IP address must resolve backwards to your mail server's name. If mail.example.com is 203.0.113.10, then 203.0.113.10 must resolve back to mail.example.com.

Only your ISP or hosting provider can set this — it is not in your domain's DNS. Ask them. Many large providers (Google, Microsoft) reject mail from IPs with no matching PTR record, so this is not optional.

Check what is there today:

Resolve-DnsName -Type PTR 10.113.0.203.in-addr.arpa
Name                             Type   TTL   Section    NameHost
----                             ----   ---   -------    --------
10.113.0.203.in-addr.arpa        PTR    3600  Answer     mail.example.com

DNS name does not exist means there is no PTR record, and you should open a ticket with whoever owns the IP address before you go live. Note the reversed octets: 203.0.113.10 becomes 10.113.0.203.in-addr.arpa.

3.5 A database

hMailServer stores accounts, domains, message metadata and settings in a database. The message bodies are files on disk (§3.1), not rows — so the database stays small relative to Data\.

You have four choices. The installer's database page asks only "built-in or external"; if you pick external, DBSetup.exe runs after the file copy and asks which external engine, for the host, database name and credentials.

Database [Database] Type in the INI Good for What is bundled What you must have first
Built-in (SQL Server Compact 4.0 SP1) MSSQLCE Getting started; small installations SSCERuntime_x64-ENU.msi, installed by setup Nothing. This is the default
MySQL / MariaDB MYSQL Most production use MariaDB Connector/C 3.4.9 as Bin\libmysql.dll, plus its authentication plugins under Bin\plugin\ A reachable server, an empty database, and a user that may create tables
Microsoft SQL Server MSSQL Windows shops that already run it Nothing — uses the OS's own data stack The same, including Express edition
PostgreSQL PostgreSQL Larger installations libpq from PostgreSQL 18.3 The same

(Type strings from IniFileSettings.cpp:129-136; bundled clients from installation/section_files_common.iss and section_files_64.iss. Versions cross-checked in Third-Party Binaries.)

If in doubt, take the built-in database. You can migrate later — see Migrating the Database Backend — and for anything up to a few dozen mailboxes it is entirely adequate.

Two things about the built-in engine are worth knowing before you choose it:

  • It runs on a single database connection. IniFileSettings::LoadSettings forces NumberOfConnections to 1 for MSSQLCE, with the comment "SQL CE is supposed to be ACID, robust and so on but isn't really". That is fine for small installations, and it is the first thing to change if the server feels slow under concurrency.
  • Microsoft has withdrawn the SQL Server Compact download. The copy in installation/SQLCE/ is the archive of record (see Third-Party Binaries). It still installs; there is simply nowhere upstream left to fetch it from.

What the installer leaves in Bin\hMailServer.INI for the built-in engine:

[Database]
Type=MSSQLCE
Database=hMailServer
Server=
Username=
Password=<encrypted>
PasswordEncryption=6
Port=0
Internal=1

The password for the built-in database is generated randomly by the server (InterfaceDatabase::CreateInternalDatabase) — you never see it and never need it. PasswordEncryption=6 is DPAPI, machine-scoped, so the value cannot be decrypted on another machine; it falls back to the legacy Blowfish scheme (1) only when ProtectStoredSecretsWithDPAPI is turned off. That machine scope matters for Backup and Restore: a restored INI on a different machine cannot decrypt it.

3.6 Decide your host name

Pick the name your mail server will be known by — conventionally mail.yourcompany.com. Write it down. It is used in five places that must all agree:

Where What it is What happens when they disagree
Your domain's MX record Where other servers send your mail Mail does not arrive
The PTR record on your IP The reverse lookup Google and Microsoft refuse or spam-file your mail
Your TLS certificate's subject The name clients verify Clients warn, or refuse to connect
Connections & protocols → Protocols → SMTP → Host name (HELO/EHLO greeting) What you announce in the 220 banner and in HELO/EHLO Receiving servers score you up as spam; some refuse outright
Your mail clients' server setting What users type A certificate warning for every user, every time

Pre-flight checklist

  • Windows machine, 64-bit, build 14393 or newer, always on
  • Administrator access to the Windows machine
  • Domain name with DNS access
  • Static public IP
  • Port 25 open inbound and outbound, both tested (§3.3)
  • Ports 587, 143 and 993 planned for your users
  • PTR record requested from your provider
  • Host name chosen (mail.yourcompany.com), and the same name planned for the MX record, the PTR record and the TLS certificate
  • Database chosen; if external, the server is reachable and an empty database exists
  • Antivirus exclusions planned for Data\, Database\ and Temp\
  • An administrator password chosen and in your password manager — setup asks for it, it must be at least five characters, and it is the master password for the whole server

Next: Installing hMailServer.


Clone this wiki locally