hMailServer 6.2.18

Built 12 August 2026 6.2 series

This is not the current release. hMailServer 6.3.3 is the one to install unless you need this exact version.

Downloads for 6.2.18

Windows

Windows 10 (version 1607 or later) and Windows 11, or Windows Server 2016 and newer; 64-bit only. Run the installer as an administrator: it upgrades an installation older than this version in place, and it cannot go backwards — an older server refuses a database a newer one has upgraded, so back up the database and the data directory first. It is not Authenticode-signed, so Windows names an unknown publisher and SmartScreen warns before it will run it.

  • hMailServer-6.2.18-x64.exex64 · 71.8 MB
    Download
    SHA-256acff774378fa…994d8b0e

What’s new in 6.2.18

6.2.17 bounded message acceptance, which was the mechanism behind #18. This release finishes the job on the delivery side, and fixes the one place where adding a bound made things worse.

Full release notes for 6.2.18 8 sections

The database-unavailable fix

The most consequential change here is not a timeout. It is that a recipient lookup which fails because the database did not answer now returns 451 rather than 550.

The two cases were indistinguishable inside the server: a lookup that failed and a lookup that found nothing were reported identically. So a database briefly locked by a backup told the sending server that a perfectly valid mailbox did not exist, and the mail was bounced instead of retried. That is mail loss with a delivery receipt.

It is implemented as a thread-local marker set at the two points where the connection pool gives up, read at both RCPT TO decision points. One detail worth recording because it is easy to get wrong: the marker is set after the pool lock is released and before ReportError, because the error handler can re-enter the pool on the same thread and deadlock against it.

This is also what made it safe to turn the pool deadline on: DBConnectionAcquireTimeout now defaults to 60 seconds rather than 0. It shipped disabled in 6.2.17 precisely because timing out an acquisition turned a slow database into a bounce. It no longer does.

Bounded waits (#23, #24)

Every remaining wait that could occupy a thread from a shared pool now has a ceiling, and the log names which one was hit.

  • Outbound delivery sessions have an absolute ceiling (ClientSessionCeiling, 30 minutes) that is separate from the idle timeout. The idle timeout is re-armed on every byte received, so a peer dribbling one byte at a time held a delivery thread indefinitely — the idle timeout never fired because the peer was never idle.
  • ClamAV on the delivery path (#23) is bounded and reports a timeout rather than holding the thread.
  • DNS queries, event scripts and external scanner processes (#24) are bounded by DNSQueryTimeout (10s), ScriptTimeout (60s) and ExternalProcessTimeout (300s).
  • Work queue saturation is reported on a schedule and names the task holding each thread, with its session and peer IP.
  • Pre-authentication IMAP command buffering is capped at 11 MB. An unauthenticated peer could previously buffer without limit.
  • Backup restore validates the source archive before deleting the target.
  • It deleted first, so a corrupt archive destroyed the data it was restoring over.

Static analysis

First /analyze pass. The findings worth naming:

  • GetExecutableName and two MySQL path helpers allocated a byte count where a character count was needed — a buffer overrun on long paths.
  • Logger::WriteLogFile shadowed fileExists, so rotation tested an uninitialised value and could corrupt the log it was rotating.
  • Every read of the virus-scanner counter is now interlocked, and the compare-and-swap uses the value it compared against rather than a fresh non-atomic read.

Roadmap

Roadmap.md is rewritten after a comparison against Postfix + Dovecot, Stalwart, iRedMail, Mail-in-a-Box and Exchange Online.

It states plainly what this fork is ahead on, because a list of gaps misleads on its own: in-process MTA-STS (Postfix still has none native), DANE with in-process DNSSEC validation, ARC sealing, IMAP4rev2 advertised by default (Dovecot ships it compile-time experimental and off), SCRAM-SHA-256-PLUS with channel binding, and observability in the open tier that Stalwart charges for.

Then the gaps that actually cost users — full-text search, shared and delegated mailboxes, Sieve depth, per-account send limits, message trace — each with a note on what is already in the tree that a fix would reuse.

It adds a section on graphs and visual data, including three accessibility defects in the current Control Panel dashboard, and reasoned refusals for JMAP, CalDAV, webmail, active/active clustering, ActiveSync/EWS and mobile push — with the reason in each case rather than a bare no.

Also flagged as time-sensitive: hMailServer can only present a username and password when relaying out through, or collecting from, Microsoft 365. Basic auth for SMTP AUTH there is scheduled off by default at the end of December 2026, so OAuth 2.0 client support (XOAUTH2) is now dated work, not speculative.

Documentation

DiagnosingStalledMail.md gains the delivery half and the corrected DBConnectionAcquireTimeout default.

Verification

1049 regression tests pass against this exact binary, up from 1038. New coverage for recipient verification (4), IMAP sequence sets (12) and aborted transfers (2).

The delivery ceiling was verified against a deliberately hostile peer rig — the kind that dribbles bytes to defeat an idle timeout. That rig is what caught a bad_weak_ptr crash from calling shared_from_this() in a constructor; the timer is now armed from Start().

Still open

Discussion #18 — the root cause is found, fixed and bounded, and the tracking issue for it is closed, but it has not been confirmed against the original reporter's Postfix/PMG setup. That confirmation is the one thing still missing. If you are affected, the per-stage timings described in the troubleshooting guide will name the culprit in a single log line; please post it on the discussion.

Correction (12 Aug 2026)

A follow-up audit of the source tree found that ARC sealing is narrower than described above and in the roadmap. Arc::Seal has a single caller, sitting after every early return in DKIMSigner::Sign, so a message is sealed only when the sender's domain is hosted on this server and has DKIM enabled and signing succeeds. Relayed third-party mail — the case ARC exists for — is never sealed.

Until that is fixed this should not be presented as an advantage over verify-only implementations, and the roadmap now says so. The same audit turned up fifteen other defects, all listed there.

Release facts

Version
6.2.18
Packages
1Windows, x86-64
Installer SHA-256
acff774378fa…994d8b0ehMailServer-6.2.18-x64.exe

Every file in 6.2.18

Full SHA-256 of each file as recomputed on this server. The SBOM is not needed to install; it lists every component in the build. Nothing in this release is signed — the signing workflow came later — so the hash above is this server’s own recomputation rather than a check against something the project signed.

FileWhat it isSizeSHA-256Signature
hMailServer-6.2.18-x64.exeWindows installer · x6471.8 MBacff774378fa5f7480e3673fa4eab0f8603289a6d54558c55621c767994d8b0e
hmailserver.spdx.jsonSBOM (SPDX)Every component in the build, in SPDX JSON.96 KB147b09b4d08ea8f90c67a794ab8357d6ddfa02ea8637329029e70282c57d05c9
hmailserver.cyclonedx.jsonSBOM (CycloneDX)The same inventory in CycloneDX JSON.50 KBf319376b9bac0f417af941de9b9c00220207a34fac5f783a40cf97a1dacd52c8