> ## Content Index
> Fetch the complete content index at: https://blog.diengdoh.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Plesk License Expired: What Still Works and How I Got Around It
- URL: https://blog.diengdoh.com/plesk-expired-license-what-still-works/
- Published: 2026-08-10T10:00:00.000Z
- Updated: 2026-10-11T10:16:27.000Z
- Description: An expired Plesk license blocks the panel and the plesk CLI, but sites and mail keep running. How I restored a mailbox anyway with mailmng-core.
- Author: Lukas
- Tags: Linux, Security

A Plesk box I look after ended up running on an expired license. It had been a trial, the trial ran out, and the decision on whether to buy a real license (or move off Plesk entirely) wasn't made yet. Meanwhile the server had to keep doing its job — and then I needed to restore a mailbox on it.

Turns out an expired Plesk license is a strange half-state. Most of the server keeps running just fine. The panel and the `plesk` CLI refuse to do anything. And underneath that, Plesk's own low-level tools still work, if you're willing to talk to them directly.

**TL;DR:** With an expired license, websites and mail keep serving. The web UI and every `plesk bin ...` command refuse with a license error. Let's Encrypt auto-renewal through Plesk stops — move TLS to certbot before your certs expire. `plesk db` still works. And the mail backend tools in `/usr/local/psa/admin/sbin/` (`mailmng-core`, `mailmng-domain`, `mailmng-outgoing`) don't check the license — that's how I restored a mailbox without the panel.

## What keeps running

From what I saw on this box:

- **nginx/Apache keep serving sites.** Existing vhost configs stay in place, PHP-FPM keeps running.
- **Postfix and Dovecot keep running.** Mail in and out, IMAP logins, SMTP AUTH — all fine.
- **MySQL/MariaDB keeps running**, and you can still reach it as Plesk's admin user from the shell:

```bash
mysql -uadmin -p"$(cat /etc/psa/.psa.shadow)"

```

- **`plesk db`** — the shortcut into Plesk's own database — still works. I only used it for `SELECT`s to see what Plesk thought the mail config looked like. I wouldn't write to the Plesk DB by hand.
- **fail2ban, unattended-upgrades, cron, Docker** — anything that isn't Plesk doesn't care about Plesk's license.

## What stops

- **The panel UI** on `:8443` — you get the license screen and nothing else.
- **Every `plesk bin` command.** Creating a domain, a database, a mailbox, changing a PHP handler — all of it fails with a "license key has expired" message.
- **Let's Encrypt renewal through Plesk.** The certificates already installed keep working until they expire. Then they don't, and nothing renews them. That's the one that actually takes sites down, weeks later, when nobody remembers the license. I wrote up the escape route in [moving Plesk's Let's Encrypt to certbot](/plesk-letsencrypt-expired-certbot-migration/) — do it while you still have time.
- **Licensed add-ons** that hang off the Plesk license. On this box there were pending updates for a security add-on whose license status depends on Plesk's; I wouldn't count on those updating.
- **Domain limits.** A trial or small license comes with a domain limit. On an expired license I didn't test what Plesk enforces and when — but I wouldn't bet the sites on "it's been fine so far".

## The job: restore one mailbox

A printer with scan-to-email sends its scans through this server. It logs in via SMTP AUTH to its own mailbox on this server and sends from there. That mailbox existed on an older server that was gone; it wasn't part of what got migrated. I had the old server's full Plesk backup locally.

Normally: create the mailbox in the panel, set the password, done. With the panel dead, `plesk bin mail --create` refused too.

Two useful things were in the backup:

- the **Maildir**, in the domain's `backup_domainmail_*.tzst`
- the **mailbox password**, in the domain's `backup_info_*.xml` — stored as `<password type="plain">`. In plain text.

That second one is a security note on its own: a Plesk backup can contain mailbox passwords in plaintext. Treat the backup files like a password database. Encrypt them at rest, restrict who can read them. In this case it was convenient: same password, so the printer didn't need reconfiguring.

## Gotcha: mailmng-core and friends don't check the license

`plesk bin mail` is just a front end. The actual work on Postfix/Dovecot is done by tools in `/usr/local/psa/admin/sbin/`:

```bash
ls /usr/local/psa/admin/sbin/ | grep mailmng
# mailmng-core, mailmng-domain, mailmng-outgoing, ...

/usr/local/psa/admin/sbin/mailmng-core --help

```

These didn't check the license. What I used:

| Tool             | Actions                                                         |
| ---------------- | --------------------------------------------------------------- |
| mailmng-core     | \--add-domain, \--add-mailname, \--add-mailbox, \--set-password |
| mailmng-domain   | \--set-domain-key, \--install-certificate                       |
| mailmng-outgoing | \--add-subscription, \--add-mailname                            |

They take their input as **JSON on stdin**, with `--wait-stdin`. The password for `--set-password` comes from the `PSA_PASSWORD` environment variable, not from an argument — good, it doesn't land in the process list or shell history.

```bash
# shape only — build the JSON from --help and your existing config
/usr/local/psa/admin/sbin/mailmng-core --add-mailname --wait-stdin < mail.json

PSA_PASSWORD='the-old-password' \
  /usr/local/psa/admin/sbin/mailmng-core --set-password --wait-stdin < mail.json

```

I'm not going to paste a full JSON here because I'd be guessing at fields for your Plesk version. What I can tell you from making it work:

- The `--help` output does **not** list everything that's required. My calls failed until I added a `maillists` field that the help never mentioned.
- `certificates` belongs on the **top level** of the JSON, not inside the `domain` object.
- Once you have a JSON that works, keep it. Next time you'll need it again.

## Gotcha: the order of calls

`--add-domain` failed on the first try because it wanted to set a quota and the mailname directories didn't exist yet. The sequence that worked:

1. `--add-domain` — fails at the quota step, ignore it
2. `--add-mailname`
3. `--add-mailbox`
4. `--add-domain` **again** — now it succeeds, and the domain shows up in Postfix's `virtual_domains` map

Then copy the Maildir from the backup into the mailbox directory, fix ownership, done.

## Gotcha: "You are not allowed to use sendmail utility"

The mailbox could log in and receive. Sending failed with *"You are not allowed to use sendmail utility"*. That message comes from Plesk's mail milter (`psa-pc-remote`, listening on a local port), which only lets known senders through. The mailname has to be registered with `mailmng-outgoing` as well (`--add-subscription`, then `--add-mailname`). After that, the printer could send.

## Gotcha: back up the Postfix maps first

Before touching anything, I copied Postfix's map files to a dated directory under `/root/`. The same server hosts other domains' mail, and these tools rewrite shared maps. If something had gone sideways, I wanted the old state of everything one `cp` away. I also checked afterwards that the other domains' mail was untouched.

## TLS for the mail hostname

The printer connects to a `mail.` hostname, so that name needs a valid certificate on SMTP. I got it with certbot (webroot on Plesk's default vhost, not the site docroot — the ACME challenge is served from there), installed it into Postfix's SNI map with `mailmng-domain --install-certificate`, and added a certbot deploy hook so renewals re-install it. Same pattern as in the [certbot migration post](/plesk-letsencrypt-expired-certbot-migration/).

## Verifying

```bash
# SMTP AUTH on submission
openssl s_client -connect mail.example.com:587 -starttls smtp -quiet
# then EHLO, AUTH ... by hand, or use swaks:
swaks --to someone@example.org --from scan@example.com \
      --server mail.example.com:587 --tls --auth-user scan@example.com

# IMAPS login
openssl s_client -connect mail.example.com:993 -quiet

```

SMTP AUTH on 587 worked, IMAPS login worked, inbound delivery worked.

## Gotcha: delivery still failed — DNS

Sending worked from the server's side, and the big mail providers still rejected the scans. The domain had **no SPF, no DKIM, no DMARC** records. Gmail rejects that with `550-5.7.26` (unauthenticated sender). Nothing on the server fixes that; the records go into the DNS zone. Whether Plesk's DKIM signing even runs on an expired license I didn't verify — a locally delivered test mail had no DKIM header. SPF alone gets you past the hard rejection in many cases, but set all three. And [lower the TTL before you change DNS](/lower-dns-ttl-before-migration/) if your zone has day-long TTLs.

## The panel itself

One more thing: an expired panel on `:8443` is still a login page on the public internet. It does nothing useful anymore, so I'd restrict it to your own IP until the license question is decided — with the [host firewall](/ufw-firewall-rules-ubuntu/), carefully, since Plesk and fail2ban have their own iptables chains. And SSH should be key-only regardless — see the [SSH hardening checklist](/ssh-hardening-ubuntu-checklist/).

## Buy, or leave?

Running Plesk on an expired license works for a while if you know where the levers are. It's not a state to stay in: you can't manage anything through the supported paths, and every change is you reverse-engineering Plesk's internals. Either buy the license or move to something that doesn't stop working when a key expires — for example [KeyHelp as a free Plesk alternative](/keyhelp-free-plesk-alternative/).

---

### Related posts

- [My Server Ran Out and My Backups Were Truncated: What I Learned](https://blog.diengdoh.com/server-provider-outage-backup-lessons/)
- [Tailscale vs WireGuard — Which VPN Should You Actually Run?](https://blog.diengdoh.com/tailscale-vs-wireguard/)
- [One Public IP, Many VMs — Port-Splitting a Proxmox Host with nftables](https://blog.diengdoh.com/proxmox-one-public-ip-multiple-vms/)