---
title: "Aliases, distribution lists, membership queries, mailing lists and public folders"
url: https://www.hmailserver.co.uk/topic/28270/aliases-distribution-lists-membership-queries-mailing-lists-and-public-folders
author: "Progressiverobot"
published: 2026-09-27T19:52:13.731Z
updated: 2026-09-27T19:52:13.731Z
category: "Rules, Sieve & routing"
tags: ["smtp","imap","administration","dkim","dmarc"]
site: hMailServer Community Forum
---

# Aliases, distribution lists, membership queries, mailing lists and public folders

*Written for 6.3.4. hMailServer 6.3.7 (17 October 2026) signs an authenticated submission as another hosted domain only when the account may send as the address its From names - its own, an alias pointing at it, a mailbox that granted it the post right, an address it proved, or a masked address of its own; otherwise the mail is sent unsigned as that domain, so give such an account the alias or the grant before upgrading. Mail from outside whose From names a hosted domain is no longer signed as it, nor is an alias's or a distribution list's copy of it to an outside address; where such a message did not pass DMARC for the organisation its From names when it arrived, a copy whose envelope sender is at this server's host name, or at a hosted domain or a subdomain of one, in that organisation is not sent where an alias or a distribution list expands to an outside address, a managed list does not distribute a posting whose From names the list domain's organisation, and a distribution list's bounce address is not given to it; a managed list's copies of a posting from outside are not signed as the list's domain when an address of the list domain's organisation is in its From fields. Creating a domain alias is now the server administrator's: a credential confined to named domains is refused it, over REST and over COM. See [the 6.3.7 announcement](/topic/28277).*



There are three ways of making one address reach somewhere other than a mailbox of the same name - an alias, a distribution list and a route - and one way of giving several people the same folder. This topic covers all of them as they are in 6.3.4 (27 September 2026, schema 6104): aliases, domain aliases and plus addressing; distribution lists, who may post to them and how moderation works; the **membership query**, which lets a list define its own members; the **list manager**, which turns a distribution list into a mailing list people join and leave themselves; and public folders with their permissions. The membership query and the list manager are new in 6.3.4; the distribution list itself is in every release. The one thing to know first: **the address is resolved in one function (`RecipientParser::CheckDeliveryPossibility`), in a fixed order, and an account always wins.**

### The order an address is resolved in

At `RCPT TO` the server works through this, and stops at the first answer:

1. **Domain aliases** rewrite the domain.
2. **Plus addressing** trims the local part.
3. **Account?** If found, deliver to the mailbox.
4. **Alias?** If found, follow it and start over, up to 25 hops.
5. **Distribution list?** If found, expand to the members, or to the moderator.
6. **Route?** If found, send to the route's target server.
7. The domain's **postmaster address**, the catch-all: when nothing above matched, the resolution starts again with that address, which is why a mistyped address is delivered there rather than refused. If it is empty, `550 Unknown user`.

*Since 6.3.4* one question is asked before all of these: **is the address, or its domain, routed to a webhook?** A webhook route that only posts takes the address's mail **instead of** its mailbox, alias or list - a list whose address is routed never sees the message, nor applies its posting rules to it. Route the addresses you mean rather than a list's whole domain; [mail in to a webhook](/topic/28266) has the routes themselves.

### Aliases

An **alias** is a second address that delivers to an existing target. In the Control Panel: **Accounts & domains → Domains**, select the domain, then the **Aliases** panel.

**The Control Panel and COM are Windows-only.** On Linux, where there is neither, [the Control Deck](/topic/28192) is the administration people click through, and it is the front end of the REST API, which both platforms have:

| What | REST route |
|---|---|
| A domain's aliases | `GET` and `POST /api/v1/domains/{domain}/aliases`; `DELETE /api/v1/aliases/{address}` |
| A domain's other names | `GET` and `POST /api/v1/domains/{domain}/domain-aliases`; `DELETE` on `.../{name}` beneath it |
| A domain's lists | `GET` and `POST /api/v1/domains/{domain}/lists`; `PUT` and `DELETE /api/v1/lists/{address}` |
| A domain's plus addressing | `PUT /api/v1/domains/{domain}` (`plus_addressing_enabled`, `plus_addressing_character`) |

The Control Panel paths and COM properties below are for Windows.

| Field | COM property | Meaning |
|---|---|---|
| Alias address | `Alias.Name` | The address people send to. Must be in this domain |
| Target | `Alias.Value` | **May be anything**: another account here, another alias, a distribution list, an address covered by a route, or an address at a different server |
| Active | `Alias.Active` | Unticked: `RCPT TO` is answered `550 Alias is not active.` - *not* passed on to the catch-all |

- **The target replaces the address and resolution starts again**, so an alias may point at an alias, which may point at a list. Beyond **25** hops the answer is `550 Mail server configuration error. Too many recursive forwards.`
- **An alias is only consulted when no account has that address.** Creating `sales@` as an account after `sales@` exists as an alias silently changes where the mail goes.
- **An alias to an external address is treated as inbound mail, not as relaying**, so `user@yourcompany.com → user@gmail.com` works for external senders without opening a relay.

*Since 6.3.4* three more kinds of second address exist, and they are the person's own rather than the administrator's: **the alias a mailbox move leaves** ([renaming or moving a mailbox](/topic/28244) keeps the old address as an alias of the new one by default); **masked addresses** (schema 6067), which the person makes in the webmail for one shop or sign-up and which, switched off, are refused as an address that never existed; and **verified send-as** (schema 6066), which receives nothing here - it is a *From* address, not an alias.

**Domain aliases.** **Accounts & domains → Domains → Properties → Names**. The rewrite is total: `anything@yourcompany.net` becomes `anything@yourcompany.com` before anything else is looked at. You do not create per-address aliases for an alias domain; the **sender** address is rewritten too, which is what lets a list in *membership* mode recognise a member who posts from the alias domain; and the alias domain needs its own MX record. Since 6.3.7 adding one is the server administrator's: a credential confined to named domains - such as a domain administrator, or an API key issued for its domains - is refused, over REST and over COM, because a domain alias decides what names the server accepts mail for.

**Plus addressing** is off by default and enabled per domain on **Accounts & domains → Domains → Properties → Limits** (default character `+`). With it on, `alice+invoices@example.com` resolves to `alice@example.com`, and the full original address is still in the `To:` header. It applies to the recipient address only, after domain aliases and before the account, alias and list lookups. When off, `alice+invoices@` is an unknown address.

### Distribution lists

A **distribution list** delivers one message to many recipients. In the Control Panel: the **Distribution lists** panel of the domain, then **Properties** and **Members**.

| Mode | Stored value | Who may post | Refusal |
|---|---|---|---|
| **Public - anyone can send** | `0` | Anyone at all | - |
| **Membership - only list members can send** | `1` | Any address on the member list, after domain aliases are applied to both sides | `550 Not authorized sender.` |
| **Announcements only** | `2` | Only the address in **Require sender address** | `550 Not authorized owner.` |
| **Anyone in the domain can send** | `3` | Any sender whose domain is the list's own | `550 Not authorized domain.` |
| *(on any mode)* **Require SMTP authentication** | flag | An unauthenticated session is refused first | `550 SMTP authentication required.` |

**"Anyone in the domain" is a claim, not a proof.** `MAIL FROM` is free text, so an outsider can assert a local address. Tick **Require SMTP authentication** with that mode or the list is open to the Internet. A fifth mode, `4`, "Anyone with a server account can send", existed only in the type library and behaved as Public; `put_Mode` now refuses the value and the option is gone from the dialog.

One more check runs for every mode, Public included: the poster must be allowed to reach every recipient of the list, so a list containing a members-only list the poster is not in is refused as a whole.

**Moderation.** Set a **Moderator** address and a posting the rules above would refuse is accepted with `250` and forwarded to the moderator instead, stamped `X-hMailServer-Moderation`. The moderator approves it by resending it to the list from an authenticated session; that authentication is the security boundary and is unconditional. Three failures are numbered in the log: `6360` (the moderator was removed between the check and the expansion), `6361` (the moderator address does not resolve; the recipient is refused with `550`) and `6363` (the list is its own moderator).

**Bounce address.** Empty means bounces go to the poster. Set, it becomes the envelope sender of every copy, so a dead subscriber's bounce reaches the list owner, and an external member's server evaluates SPF against the list's own domain. A bounce address pointing at the list itself is ignored, with error `6362`.

**Headers.** An unmanaged list adds `List-Id`, `List-Post` (the literal `NO` for an announcements-only list), `List-Help`, `List-Owner` and a `mailto:`-only `List-Unsubscribe`, before DKIM signing. Nothing is added when the message already carries a `List-Id`, or when the list or owner address is not US-ASCII.

### A list that defines itself: the membership query, since 6.3.4

*Schema 6074.* A list can carry a **membership query**: one short text that says who its members are, answered against the server's accounts at the moment a message is sent to it. `everyone@example.com` with the query `domain` reaches every active account of the domain on the day, including the person who joined this morning and not the one switched off last night.

| Query | Members |
|---|---|
| *(empty)* | A static list: the addresses under Recipients and nothing else |
| `domain` | Every **active** account of the list's own domain |
| `domain:other.example` | Every active account of that domain, which this server has to host |
| `pattern:sales-*@example.com` | Every active account whose address matches the wildcard; `*` is any run, `?` exactly one, case ignored |
| `everyone` | Every active account of every active domain on the server |

- **It is a union with the list's own recipients**, never a replacement. An address that is both is delivered to once.
- **It answers accounts only** - not aliases, other lists or outside addresses - and never a disabled account or an account of a disabled domain.
- **It is resolved once per SMTP transaction**, not once per `RCPT TO`, and nothing is stored.
- **Who may set which form.** A domain administrator, or an API key with a domain scope, may set `domain` or a `pattern:` in a domain it holds. `everyone`, `domain:` naming another tenant's domain, and a pattern whose domain part is itself a wildcard are the server administrator's. The same rule governs reading the answer: `GET /api/v1/lists/{address}/members` answers **403** to a confined credential when the query reaches past its domains.
- **A query is judged when it is saved.** `domain:` naming a domain this server does not host, a `pattern:` with no `@`, or any text that is none of the five forms is refused, by the same sentence over COM, over REST and in the Control Panel.
- **"Answers nobody" and "could not be answered" are different.** A query whose named domain has been deleted is not an error at delivery: the message goes to the list's rows and code 6980 is logged. But when the accounts **cannot be read** - the database locked by a backup - the recipient is refused `451 4.3.2` and the sender retries, with code 6982, and the members route answers **503**.

It is set as *Membership query* in the Control Panel's list dialog and the Control Deck, `membership` over REST, `DistributionList.Membership` over COM, and `hmctl list update all@example.com --set membership=domain`. The Deck's list editor shows **Delivers to now**, each address marked *Kept by hand* or *From the query*.

### The list manager: a mailing list, since 6.3.4

*Schema 6092.* A distribution list with the **list manager** switched on is one people join and leave themselves. Nothing changes for a list until it is switched on: every list an upgrade finds is unmanaged.

1. **On the list**: *Managed* in the Control Panel's list dialog, `managed` in the Deck's list editor and on `PUT /api/v1/lists/{address}`, or `DistributionList.Managed` over COM.
2. **The links.** The confirmation page, each member's page, the owner's approval page, the subscribe form and the archive are served by the **REST listener**, which is off until `RestApiPort` is set ([turning the REST API on](/topic/28264)). Make it reachable over HTTPS, then set `list_base_url` (`ListBaseUrl`), such as `https://lists.example.com`. Empty, the default, offers no link at all. **Only an `https://` base gives RFC 8058's one-click.**
3. **DKIM on the list's domain.** The copies are signed as that domain after the list's fields are in place, so the signature covers `List-Unsubscribe` and `List-Unsubscribe-Post`. With DKIM off for the domain the copies go unsigned and the providers do not offer the one-click.

| Address | What it does |
|---|---|
| `team@example.com` | Post to the list |
| `team-subscribe@example.com` | Ask to join, and confirm by replying |
| `team-unsubscribe@example.com` | Ask to leave: the member is sent a link and a token, and nothing more happens until they follow it |
| `team-request@example.com` | The help text |
| `team-owner@example.com` | The person who runs the list |
| `team-bounces@example.com` | Delivery reports; with VERP, `team-bounces+jo=example.org@example.com` |

None of them is an account; an account, an alias or a list of exactly one of those names is the administrator's and wins over the manager.

**Joining.** `subscribe_policy` is **0 closed** (the default: the administrator adds members), **1 confirm** (the address asked for is sent a confirmation with a token) or **2 moderated** (after the address confirms, the owner approves on a page, signed in to the webmail as the owner's own account, or on the Deck; a reply by mail approves nothing). The list answers at most twenty requests an hour from one requester and two hundred an hour in all.

**Delivery.** Each member chooses **each** message, one **digest** a day, or **none**. With `digest` on, one digest goes at `digest_hour` (7 by default, the server's local time), at most 100 messages and 10 MB. With `archive` at 1 (members) or 2 (public), every distributed message is kept and shown by month, **as text only**, never as HTML. The rows of `hm_listarchive` are not in the backup.

**What a member's copy carries**, over an `https://` base with the archive on:

```text
List-Id: <team.example.com>
List-Post: <mailto:team@example.com>              (NO for an announcement list)
List-Help: <mailto:team-request@example.com?subject=help>
List-Subscribe: <mailto:team-subscribe@example.com?subject=subscribe>, <https://lists.example.com/lists/team@example.com/subscribe>
List-Unsubscribe: <mailto:team-unsubscribe@example.com?subject=unsubscribe>, <https://lists.example.com/lists/unsubscribe?t=...>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
List-Owner: <mailto:team-owner@example.com>
List-Archive: <https://lists.example.com/lists/team@example.com/archive>
Precedence: list
X-Loop: team@example.com
X-hMailServer-List-Member: <a tag, see Bounces>
```

**Bounces.** A `5.x.x` is a hard bounce, a `4.x.x` a soft one; a *delayed* warning counts for nothing. Anybody can write to the bounce address, so a report is believed only when it carries the member's tag, `X-hMailServer-List-Member`.

| Setting | REST key | Default |
|---|---|---|
| `ListHardBouncesToUnsubscribe` | `list_hard_bounces_to_unsubscribe` | 1 |
| `ListSoftBouncesToUnsubscribe` | `list_soft_bounces_to_unsubscribe` | 5 |
| `ListBounceWindowDays` | `list_bounce_window_days` | 30 |

A member who reaches either count is set to **none** - paused, never unsubscribed - and the owner is told once.

### Public folders

**Accounts & domains → Public folders**, in the Control Panel on Windows, creates shared IMAP folders; public folders have no REST route yet, so Linux has no administrator's page for them. On either platform a client holding the `a` right manages a folder's permissions over IMAP. Public folders live in their own namespace, `#Public`, and sub-folders are made by typing the whole path with the hierarchy delimiter, `.` by default: `#Public.Team.Archive`. `#Users.alice@example.com` is a different namespace: one account's own folders, shared.

Each permission entry grants RFC 4314 rights to an **account**, a **group** or **Anyone** (every authenticated account).

| Right | Letter | What it allows |
|---|---|---|
| Lookup | `l` | The folder appears in `LIST`/`LSUB`. Without it the folder does not exist as far as that user is concerned |
| Read messages | `r` | `SELECT` and `STATUS` |
| Keep seen/unseen state | `s` | Set or clear `\Seen` |
| Set flags | `w` | Flags other than `\Seen` and `\Deleted` |
| Insert | `i` | `APPEND` and `COPY` into the folder |
| Post | `p` | Send mail to the folder's submission address |
| Create sub-folders | `k` | `CREATE` beneath it |
| Delete folder | `x` | `DELETE` |
| Delete messages | `t` | Set or clear `\Deleted` |
| Expunge | `e` | `EXPUNGE` |
| Administer | `a` | `SETACL`, `DELETEACL`, `GETACL`, `LISTRIGHTS` |

- **An owner has every right implicitly.** For anyone else the server walks up from the folder to the nearest ancestor that has any ACL rows, then uses the row for the account, else for a group the account is in, else for Anyone.
- **The nearest ancestor with any rows wins, and rows are not merged.** Adding one permission to a sub-folder removes everyone else's access to it.
- **`\Seen` is shared in a shared folder, not per user.** Grant `lrs` and delegates share one read/unread state; grant `lr` and they leave no trace.
- **Turning ACL enforcement off** opens public folders only. It does not extend to `#Users`, which stops existing entirely.

### What it does not do

- **The list manager does not rewrite `From` for DMARC.** A posting from a domain that publishes `p=reject` reaches outside members with a `From` that fails DMARC when the list changed the message, and Gmail and Yahoo may refuse it.
- **No posting from the web**, no list password, no approval by reply, no NNTP, no IMAP access to an archive, no weekly digest, and one owner address per list.
- **A membership query has no directory-attribute form** and no `group:` form, and no query can name another list's query.
- **The list manager's fixture is not linked into the Linux test suite**: `MailingLists.md` says its thirty-four tests are of the Windows suite.

### Where to read more

- Wiki: [Aliases, Lists and Public Folders](https://gitlab.com/hmailserver/hmailserver/-/wikis/Aliases-Lists-and-Public-Folders), [Mailing Lists](https://gitlab.com/hmailserver/hmailserver/-/wikis/Mailing-Lists), [Mail In to a Webhook](https://gitlab.com/hmailserver/hmailserver/-/wikis/Mail-In-to-a-Webhook)
- Documents at the 6.3.4 tag: [DistributionLists.md](https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/DistributionLists.md), [MailingLists.md](https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/MailingLists.md)
- The public documentation: [chapter 13](https://www.progressiverobot.com/hmailserver-documentation/#13-aliases-distribution-lists-and-public-folders)
- On this forum: [Being trusted by the servers you send to](/topic/28188) for DKIM and DMARC, the [6.3.4 release announcement](/topic/28218), [the webmail in depth](/topic/28254) for masked addresses and send-as, and [IMAP on the server](/topic/28224) for shared mailboxes
