A newly created Cloudflare Tunnel profile can return “Profile not found” before its first browser login. This article explains the confirmed cause and the local code fix, plus the other issues found during review.
Reviewed build: Community plugin by fdciabdul, source commit ff0c7359f050fbca2b9efab11b61aa462d65b2d0; info.json version 1.3.0. This is a source-level review with isolated tests. Live plugin installation and Cloudflare end-to-end verification are pending. The fixes below do not make the whole plugin a certified or production-tested release.
1. Fix “Profile not found” on first login
The UI allows adding a profile without an API token. However, DnsManager.find_profile() looks in _all_profiles(), which intentionally hides profiles that have neither token nor cert_path. That filter is useful for choosing working DNS credentials, but wrong for resolving the profile that is about to receive its first browser-login certificate.
In dns_manager.py, change find_profile() to check the saved profiles first:
Code:
def find_profile(self, profile_id):
for p in self._read_profiles():
if isinstance(p, dict) and p.get("id") == profile_id:
return dict(p, virtual=False)
for p in self._all_profiles():
if p["id"] == profile_id:
return p
return None
Keep the empty-profile filter in _all_profiles(). Do not broadly treat an empty profile as valid API credentials. Our regression test creates an empty saved profile, supplies no usable profiles and verifies that find_profile still returns the intended profile for login. It passes with this change.
2. Fix unsafe UI string encoding
Profile names are inserted into single-quoted JavaScript onclick arguments using an HTML-only encoder. An ordinary apostrophe can break an action; crafted text can introduce script in the authenticated panel UI. Encode for the JavaScript string context first, then the surrounding HTML attribute. The reviewed patch uses a separate jsesc helper for those action arguments, and escapes names/errors in HTML-rendered dialogs. HTML escaping alone is insufficient here.
Do not test script injection on a live shared panel. Our six isolated JavaScript tests round-trip apostrophes, backslashes, quotes, newlines and markup without executing injected instructions. The entire UI script also parses successfully. We have not demonstrated unauthenticated panel compromise.
3. Protect installer staging and credentials
The original binary installer downloads into one predictable file under /tmp. A privileged process should use a unique private temporary directory, invoke curl/install with argument arrays, restrict download redirects to HTTPS and check command results. The review patch implements that approach. Independent checksum verification and release pinning remain future work.
Validate tunnel IDs as UUIDs before saving them or constructing credential paths. Apply mode 0600 to existing and newly relocated tunnel JSON credentials, and report relocation failures. Keep credentials out of public web directories, screenshots and support replies.
4. Fix configuration encoding and restart reporting
In ingress_manager.py, use proper quoted YAML scalar encoding rather than only replacing quotation marks. JSON-quoted strings are valid YAML scalars and handle backslashes/control characters:
The source also ignores the exit status of systemctl restart. Check it and return a failure when the restart fails:
Code:
restarted = subprocess.run(
["systemctl", "restart", SERVICE_NAME],
capture_output=True, text=True, timeout=30,
)
if restarted.returncode != 0:
return public.returnMsg(
False,
"Config written, but service restart failed: "
+ (restarted.stderr or restarted.stdout),
)
This change reports a real failure; it does not undo every previous DNS/config change. Do not describe it as complete transactional rollback.
5. Avoid DNS data loss
Before an automatic CNAME upsert, inspect every record returned for the hostname. Our patch refuses conflicting non-CNAME or multiple-record responses instead of replacing the first record. A user-selected zone must also match the hostname; stale/unavailable zone selections are rejected rather than silently redirected to another zone.
For removal, refuse records that are not tunnel-target CNAMEs and check each Cloudflare deletion response. Do not delete A, AAAA, MX or TXT records simply because they share a hostname. Our tests verify these refusal paths and confirm API errors are returned.
Remaining limitation: the patch recognizes tunnel CNAMEs by target suffix, not an ownership manifest for the particular tunnel. Full DNS/config/service rollback and concurrent-write locking are also still needed.
6. Validate before applying to a server
Back up the installed plugin directory, runtime data and /etc/cloudflared first. Match the exact source version; do not paste partial changes into an unrelated older release. Check Python syntax and run the isolated tests. Our local review passed 13 backend tests and six UI string-encoding checks, plus script parsing and diff whitespace checks.
Then use a disposable lab server to verify import, empty-profile login, account selection, credentials, origin response, generated ingress, DNS changes and actual service state. An API token accepted by the verification endpoint does not prove the zone permissions needed by this plugin. Browser login for tunnel CLI operations and the DNS API token serve different purposes.
7. What is not yet fixed or verified
Complete rollback across DNS, JSON state, config and service.
Concurrent profile login and re-login certificate isolation.
Shared locking and atomic persistence across all managers.
Independent checksum verification and a real binary update operation.
aaPanel dispatcher authentication/CSRF behavior and live end-to-end operation.
No public exploit demonstration is needed to explain these fixes. The patched download is not publicly released yet; the written changes above are available for maintainer review.
A message in Sent confirms client submission, not final delivery. Check the mail service, queue and recipient-specific log entry to find where delivery stopped.
Tested Ubuntu lab: aaPanel Free Edition 8.0.6, Mail Server 7.4.1. Postfix and Dovecot were active, /var/log/mail.log existed, and postqueue -p reported Mail queue is empty. Earlier forwarding tests recorded the original alias and successful local delivery. We did not create a deliberate external rejection for this guide.
1. Record the failing message
Write down the sending account, complete recipient address, send time and timezone, unique subject, and exact client error. Determine whether Send failed immediately or the message appeared in Sent. Use a single controlled test, rather than repeatedly sending the same message.
2. Check service status in aaPanel
Open Mail Server → Other Settings → Common settings and find Service Status. Our screen showed Dovecot, Rspamd and Postfix Running. Postfix handles SMTP transport; Dovecot provides mailbox access and can handle local delivery. A Running label does not establish that every message reached a remote inbox.
The same table contains Stop, Restart, Repair and Config controls. Read the error first. Repeated restarts can interrupt clients without fixing DNS, blocked outbound traffic or recipient rejection.
3. Read the queue on Ubuntu
In an authorized server terminal, run this read-only command:
Code:
postqueue -p
An empty queue means no mail is currently queued in this Postfix instance. It does not prove that every earlier message was delivered: an earlier message could have bounced, been removed or already left the queue.
When entries exist, identify the queue ID, recipient and displayed delay reason. A deferred message is pending for retry. Preserve the reason before changing anything. Do not empty the entire queue to troubleshoot one message.
4. Follow the matching log entry
For our Ubuntu installation:
The file path was verified in this lab. Other operating systems or logging configurations may use a different location. If a command returns no useful entries, check the logging configuration and time window; do not invent a successful result.
Search for the recipient and queue ID. One message can create several lines. Follow the same ID through submission, delivery attempt and final status. Logs may contain private addresses and message details; remove unrelated information before sharing excerpts publicly.
5. Interpret the delivery result
status=sent: the selected destination accepted that delivery. For a remote server, read its response; acceptance does not guarantee Inbox placement.
status=deferred: delivery remains pending. Read the accompanying timeout, DNS or temporary rejection reason.
status=bounced: permanent failure was reported. Read the remote explanation and any returned delivery-status message.
Authentication failure: inspect the client username, password and account status before diagnosing remote delivery.
Temporary SMTP responses generally begin with 4; permanent negative responses generally begin with 5. Diagnose the full text, not just the number.
6. Fix the cause and retest
For DNS errors, verify MX and its target. For connection timeouts, check provider port restrictions and network reachability. For authentication or reputation failures, verify SPF, DKIM, DMARC and PTR. Change one relevant setting at a time and send another unique test.
External check: our completed SEOStackTools test scored 95/100. It complements logs; it does not report the status of every message.
Use IMAP for reading email and authenticated SMTP for sending it. Both connections need the full mailbox address and a certificate matching the mail hostname.
Lab verification: mail.adminslab.com presented a trusted matching certificate on IMAP 993 and SMTP STARTTLS 587. Roundcube successfully accessed the mailbox and sent mail. This guide gives manual connection values for an email client; a specific Outlook or Thunderbird desktop installation has not been tested here.
1. Prepare the mailbox and hostname
Complete mail-domain DNS, mailbox creation and mail-service SSL first. Your mail hostname should resolve directly to the mail VPS. For Cloudflare, keep the mail A record DNS only. The webmail website address and aaPanel administration port are different services.
Open Mail Server → Mailboxes. Locate the account and confirm Status is enabled. The Login info column has a Copy link in our tested version. Treat copied login details as private: they can include the mailbox password. Do not paste them into a public support post.
2. Enter incoming IMAP settings
Choose manual configuration in your client and use:
Protocol: IMAP
Server: your certificate-covered mail hostname, for example mail.example.com
Choose the client's ordinary password authentication over the encrypted connection. Do not use the VPS root password, panel credentials or aaPanel.com account.
3. Enter outgoing SMTP settings
Server: the same verified mail hostname
Port: 587
Connection security: STARTTLS
Authentication: required, using the mailbox username and password
STARTTLS upgrades this SMTP connection to encryption; it is not the same setting as implicit SSL/TLS on port 465. Use 465 only when your own configuration confirms that endpoint is enabled. Port 25 is principally used for server-to-server delivery and is not the recommended authenticated client setting here.
4. Test both directions
Finish setup, open Inbox and compare a known message with webmail. Send a unique-subject test to an address you control. Check Sent and the actual recipient's Inbox and Junk. Reply from the external recipient and verify the response arrives. This last step checks external inbound delivery; that direction still needs a separate real-provider test in our lab.
Reference: our working Roundcube mailbox. This image shows webmail, not desktop-client setup screens.
5. Troubleshoot by symptom
Certificate mismatch: use the certificate-covered hostname and check mail-service SSL deployment. Do not accept a mismatched certificate as the normal fix.
Connection timeout: verify DNS, the intended port and both VPS/provider firewall rules.
Login rejected: check the full address, mailbox password and enabled Status.
Can read but cannot send: check SMTP authentication and STARTTLS 587 rather than changing IMAP settings.
Message appears in Sent but not at the recipient: inspect delivery logs and the queue.
Mailbox quota limits how much email one account can store. Increase it when more storage is needed, but check server disk space and the domain allowance first.
Tested: aaPanel Free Edition 8.0.6 with Mail Server 7.4.1. We changed [email protected] from 1 GB to 2 GB, verified the mailbox row, and restored 1 GB afterward. The password and enabled status were unchanged.
1. Check the current allowance
Open Mail Server → Mailboxes. Find the full email address, using Search Email if needed. Read its Quota column: our row changed from 0.00 B/1.00 GB to 0.00 B/2.00 GB. The first number is reported usage; the second is the limit. A rounded zero does not prove that the mailbox contains no messages.
Also inspect Mail Domain for the domain quota and default mailbox size. These are separate settings. Raising one mailbox limit does not create additional disk capacity. Check Home disk usage or run
Code:
df -h /
on Ubuntu. Our lab had 29 GB available during this test.
2. Edit one mailbox
1. In the correct mailbox row, click Edit.
2. Verify the dialog says Edit Mailbox and shows the intended Email Address.
3. Keep Quota limit enabled.
4. Enter the new amount in Quota, then confirm the adjacent unit. We entered 2 with GB selected.
5. Keep the existing Name and User type unless those also need an intentional change.
6. Leave Email Password empty. The dialog explicitly says an empty value leaves the password unchanged.
7. Click Confirm once and wait for the mailbox list to update.
3. Verify the result
Check the same row again. Its allowance should now show the requested value and Status should remain enabled. If the old value remains, reopen Edit and check whether the setting actually saved before trying again. Test normal mailbox access through webmail.
Screenshot: the actual lab row after the successful 2 GB change. The lab was subsequently returned to 1 GB.
4. If the mailbox is already full
Increasing the allowance can help only when the underlying server has space. Review large attachments, Sent, Junk and Trash. Export or back up messages you need before permanent cleanup. Deleting a mailbox is not a quota adjustment: it can remove the account and its mail.
Do not reduce the allowance below current usage as a routine cleanup method. First reduce stored mail or choose a sufficient limit, then verify delivery with a new message.
5. Check quota notifications
Under Mail Server → Other Settings → Common settings, our panel showed Send email when quota exceeded enabled. Check your own setting and test the notification separately; we did not deliberately fill this mailbox or verify an over-quota alert.
Reverse DNS identifies your sending server. Verify its PTR record, then send an actual message through your mailbox and review the receiving tool's authentication results.
Verified lab result, 11 October 2026: AlphaVPS configured the PTR for 217.217.235.82 as mail.adminslab.com. Public forward and reverse lookups now match, and Postfix uses that same hostname. A real Roundcube message tested with SEOStackTools Email Tester scored 95/100, Grade A: 12 passed, 2 to improve, 0 errors. SPF, DKIM, DMARC, blacklist and PTR checks passed.
1. Understand forward and reverse DNS
Forward DNS maps mail.example.com to your VPS IP. Reverse DNS maps that IP back to a hostname through a PTR record. The VPS provider controls reverse DNS for its address space. Adding a PTR record in your ordinary Cloudflare domain zone does not update the provider's reverse zone.
Use a stable mail hostname that resolves to the sending IP. Our lab uses mail.adminslab.com for forward DNS, reverse DNS and the SMTP server hostname.
2. Request or set the PTR
Check the VPS provider's Reverse DNS/rDNS/PTR settings. If no control is available, open a technical-support request with the VPS IP and desired full hostname. For example: Please set the PTR for our VPS IP to mail.example.com. Its forward A record already points to that IP.
No root password is needed for a PTR request. After the provider confirms, check public DNS rather than relying only on the ticket's status.
3. Verify both directions
On Ubuntu, these commands query a public resolver:
The first should return the desired hostname; the second should return the sending IP. The last shows Postfix's hostname. In our lab, all three agreed. If an old result remains, allow cached DNS to expire and check again. An NXDOMAIN response means that resolver found no PTR record.
4. Test with SEOStackTools
1. Open SEOStackTools Email Tester.
2. Click Get My Test Address.
3. Copy the unique recipient shown. Each test has its own address; do not copy one from a tutorial image.
4. In your webmail, click Compose and send a normal message from the mailbox you want to test to that address.
5. Return to the tool and click Check My Score.
6. Wait for the report, then review Authentication, Content & Spam Signals, Technical and Email Headers.
Send from the server being tested to the external tester. A same-server local message cannot verify the complete external delivery path.
5. Interpret the measured result
Our report showed SPF Pass, valid DKIM and DMARC alignment Pass. Under Technical, the blacklist check was Clean and Reverse DNS was Found, identifying mail.adminslab.com for the sending IP.
The two suggestions concerned HTML/plain-text structure and a List-Unsubscribe header. This test was an ordinary plain-text mailbox message. Plain-text email is valid; multipart/alternative is useful when sending an HTML version. Unsubscribe headers apply to subscription/marketing mail and relevant bulk-sender requirements, rather than every personal reply. Review suggestions in the context of the message's purpose instead of changing the server simply to increase a score.
6. Diagnose missing messages
Check Postfix logs for the exact recipient and remote response. A queued message is still pending. SMTP 250 acceptance means the receiving server accepted it; it does not guarantee Inbox placement at every provider. PTR, authentication, reputation and content all contribute to delivery.
Current status: PTR verified and external receipt/authentication tested with SEOStackTools. External inbound delivery from another mailbox provider remains a separate test. The old pre-PTR Mail-Tester result was 8.9/10; it is historical and uses a different scoring system from SEOStackTools.
An email forward sends mail for one address to another destination. Catch-all sends mail addressed to otherwise nonexistent users in a domain to a chosen mailbox.
Tested lab:[email protected] forwarded to [email protected] with catch-all disabled. A separate message to [email protected] reached the same mailbox after catch-all was enabled. These were local delivery tests; forwarding to external providers needs an additional test.
1. Create the receiving mailbox first
Create and enable the destination, for example [email protected], and verify that it receives ordinary messages. A forwarding alias does not create a separate mailbox, password or storage allowance. Do not point an alias back to itself or build a circular forwarding chain.
2. Add a forwarding address
1. Open Mail Server → Other Settings.
2. Select Mail forward.
3. Click Add Forward.
4. Keep Status enabled.
5. In Forwarded users, enter the full source address: [email protected].
6. In Domain, enter example.com.
7. In Receiving user, enter [email protected]. For multiple destinations, the dialog instructs you to put each on a new line.
8. Click Confirm and wait for Mail forwarding added successfully.
Inspect the saved Address and Goto columns. The source must be the complete address. In our version, entering only support saved an incomplete Address value, so we disabled that test entry and created [email protected] instead. A success notice alone does not validate the intended address.
3. Test forwarding independently
If catch-all is enabled, temporarily turn it off before the alias test. Otherwise it can conceal an incorrect alias by delivering any unknown address anyway. Send a message with a unique subject to the full alias, then refresh the receiving mailbox's Inbox.
Our isolated test reached [email protected]. Postfix logs recorded [email protected] as the original recipient and the admin mailbox as the delivered recipient.
4. Enable catch-all for the domain
Open Mail Server → Mail Domain. Click the domain row's Catch All switch. In the Catch email dialog, enter an existing destination in Forward email and click Confirm. You can also set the Catch All destination through the domain's Edit dialog.
Check that the switch becomes enabled. In Mail forward, the resulting domain-wide entry appeared as @adminslab.com pointing to [email protected] in our lab. This is different from a specific support@ alias.
5. Test an unused address
Choose an address that is not a mailbox or alias, such as [email protected]. Send a unique test message and verify it appears at the catch-all destination. Our test did. Existing mailboxes continue to have their own delivery rules; catch-all is intended for otherwise unknown addresses.
Manage and troubleshoot
Catch-all accepts typo addresses and can also collect unwanted mail, so use it when that behavior is useful and watch quota usage. Disable it with the domain switch when no longer needed. For a failed forward, check Status, the full source address, destination existence, loops and server logs. External forwarding may introduce SPF/DMARC complications; test that destination separately before relying on it.
Test sending and receiving separately. A message in Sent means the client submitted it; it does not prove delivery to an external user's Inbox.
Lab evidence: Roundcube submitted a message from [email protected] to the same lab mailbox, and it appeared in Inbox. A separate outbound message was accepted by SEOStackTools Email Tester and scored 95/100 (Grade A), with SPF, DKIM, DMARC and PTR passing. External inbound delivery from another provider has not yet been verified in this lab.
1. Check the setup before sending
You need an enabled mailbox, correct MX/A records, running Postfix and Dovecot, trusted mail TLS and working webmail or a configured email client. For external delivery, the provider must allow outbound SMTP traffic. PTR and sender reputation also affect acceptance.
Sign into your HTTPS webmail address with the full mailbox address and mailbox password. Our lab uses webmail.adminslab.com.
2. Compose a simple test
1. Click Compose in Roundcube's left menu.
2. Check From is your mailbox.
3. Enter a recipient address you control in To and press Enter so it becomes a recipient entry.
4. Enter a unique Subject, for example Mail test 01.
5. Enter a short normal message in Message Body.
6. Leave Save sent message in set to Sent.
7. Click Send once and wait for the result.
For an initial local test, send to your own lab mailbox. This checks submission and local storage without depending on another provider. Then repeat with an external address you control.
3. Check Sent and the destination
Open Sent and locate the unique subject. At the receiving account, check Inbox and Spam/Junk. If it arrives, reply from that external account to your aaPanel mailbox. This return message tests external inbound delivery.
In Roundcube, open Inbox and click Refresh. Open the received message and use Reply for a normal conversation test. Record which direction succeeds; avoid calling the whole setup verified when only one direction was tested.
4. Use a desktop client if required
Get your mailbox's connection details from Mail Server → Mailboxes → Login info → Copy. For our verified TLS endpoints, the hostname is mail.adminslab.com, IMAP uses 993 with SSL/TLS, and authenticated SMTP uses 587 with STARTTLS. Use the full mailbox address as username. Confirm these values against your own server configuration rather than copying the lab hostname.
5. Diagnose a missing message
Send fails immediately: read the exact client error; check authentication, SMTP service and connection settings.
Sent exists but remote delivery fails: inspect Postfix queue/logs for the recipient, status and remote rejection reason. A queued message remains pending.
Incoming mail never arrives: verify public MX, the MX target's A record, inbound port 25, provider firewall and recipient spelling.
Mail reaches Junk: inspect SPF/DKIM/DMARC alignment, PTR, content and reputation. Do not keep resending identical messages rapidly.
Next check: use SEOStackTools Email Tester to examine authentication and delivery deductions. Local receipt and an external 250 acceptance are useful evidence, but neither guarantees inbox placement at every provider.
Webmail lets a mailbox user read and send email in a browser. It is separate from the aaPanel administration dashboard and needs its own website address and HTTPS certificate.
Tested lab: aaPanel Free Edition 8.0.6, Mail Server 7.4.1, Roundcube installed on webmail.adminslab.com using PHP 8.4. The mailbox login worked over HTTPS, and a test message appeared in Inbox.
1. Prepare DNS and a mailbox
Create an A record named webmail pointing to your VPS IPv4 address. Our Cloudflare lab kept this record DNS only for installation and certificate validation. This web address is different from mail.example.com, the SMTP/IMAP hostname. Create an enabled mailbox before testing login.
2. Install through the mail-domain row
1. Open Mail Server → Mail Domain.
2. Find your domain and click Not Installed in the WebMail column.
3. In Install WebMail, enter webmail as the domain prefix. Check the complete address displayed beside the field.
4. Select an installed PHP version compatible with the bundled webmail. We used PHP-84; do not assume the newest PHP version is supported by every bundled application.
5. Click Confirm and wait for WebMail Installation Successful.
The domain row should change to Installed. The success notice directs you to Website → PHP Project, where the new webmail site can be managed. In this tested version, the older Other Settings WebMail controls were disabled and pointed back to Mail Domain. Use the domain-row installer instead.
3. Enable HTTPS on the webmail website
Open Website, find webmail.example.com and select its Not Set SSL button. Select Let's Encrypt → File Verification, check the webmail hostname and click Apply. Its DNS must point to the server, and port 80 must be reachable for this validation method.
Wait for Deployed and verify that the certificate's domain list includes webmail.example.com. Our certificate showed 89 days remaining. Mail-service TLS for mail.example.com does not automatically give this separate webmail website a matching certificate.
4. Sign into Roundcube
Open https://webmail.example.com. Enter the full mailbox address, such as [email protected], and that mailbox's password. Click Login. Do not use the VPS root password, panel username or aaPanel.com account.
A successful login displays Inbox, Drafts, Sent, Junk, Trash and Compose. Check the browser's hostname and certificate before entering credentials.
Troubleshooting
Default website appears: check the webmail DNS record, site domain binding and HTTPS certificate.
Login rejected: check the full email address, mailbox password and enabled Status.
PHP warning or parsererror: our bundled Roundcube emitted an E_STRICT deprecation on PHP 8.4. We turned off public error display for this site's PHP configuration, kept error logging enabled and reloaded its PHP service. This restored inbox requests. Review logged compatibility issues and use a supported release; hiding public warnings is not a substitute for fixing application errors.
Result: webmail installed, HTTPS certificate deployed, mailbox login and local message receipt verified.
A mail domain does not automatically create email users. Create a mailbox with its own password and storage quota before trying to sign into webmail or a mail client.
Tested lab:[email protected] was created, enabled and assigned a 1 GB quota with the General user type. No password is included in this guide.
1. Complete the domain prerequisites
Install and initialize Mail Server, add your mail domain and publish its mail-host A record and MX record. Configure trusted TLS for the mail hostname before sending credentials from an external client. The mailbox username, panel login and aaPanel.com account are three different accounts.
2. Open Add Mailbox
1. Select Mail Server.
2. Open Mailboxes.
3. Click Add Mailbox.
3. Enter the user's details
Name: a readable name, such as Lab Admin.
Quota limit: keep enabled when you want a storage cap.
Quota: our lab chose 1 GB. Pick a limit appropriate to the available disk and total domain quota. A mailbox cap is not a backup policy.
User type: our mailbox used General user. Do not grant administrative capabilities unless the person needs them.
Email Address: enter the local part admin and select example.com from the domain selector. The resulting address is [email protected]. Do not put the entire address into the local-part field.
Email Password: create a unique password for this mailbox and save it securely. Avoid reusing the VPS or panel password.
Status: keep enabled for a mailbox that should be able to log in.
Click Confirm. Wait for the success message before submitting again.
4. Verify the new row
The Mailboxes list should show the full address, masked password, quota, type and enabled status. Our row showed 0.00 B/1.00 GB and General user. Masked stars are expected; a screenshot does not need the real password.
The Copy control under Login info provides connection information. Check the actual server name and ports. Use the full address as the login username, the mailbox password, and the mail hostname covered by your certificate. Webmail installation is a separate task.
5. Test access and delivery separately
Successful login proves credentials work; it does not prove external email delivery. Send a message to an external address you control and reply back. Check Inbox, Spam and server logs. Keep an error's exact text if either direction fails.
Troubleshooting
Domain missing: add it in Mail Domain before creating users.
Invalid login: use the full email address, check Status, and use the mailbox password rather than the panel password.
Quota exceeded: review mailbox and domain usage before raising limits.
Forgotten password: use the mailbox Edit control to reset it and update the user's clients.
aaPanel generates your mail-domain record values; Cloudflare publishes them when Cloudflare hosts your domain's authoritative DNS.
Tested: The lab's A, MX, SPF, DKIM and DMARC records were published in Cloudflare. Public DNS lookups returned them, and a real outbound message passed SPF, DKIM and DMARC at Mail-Tester.
1. Get the values from aaPanel
Open Mail Server → Mail Domain → DNS Record for your domain. Keep this screen open. It shows the mail hostname, MX priority, SPF text, unique DKIM public key and DMARC value. You must use your own generated DKIM key.
2. Open Cloudflare DNS
Select your domain in Cloudflare, then DNS → Records. Inspect existing records first. If you already use another mail provider, changing MX and SPF changes that existing setup; plan the migration before replacing records. Our lab had no previous MX record.
3. Add the mail A and MX records
Click Add record. Select type A, name mail, and your VPS IPv4 address. Turn proxy status off so it reads DNS only, then Save.
Add another record: type MX, name @, mail server mail.example.com, priority 10, TTL Auto. The MX target is a hostname, not an IP address or an https:// URL. Save.
4. Add sender-authentication TXT records
Add each separately:
SPF: type TXT, name @, content copied from aaPanel. Our dedicated lab used
Code:
v=spf1 +a +mx -all
This permits the A/MX senders; it is not a universal value for domains using other services. Maintain one SPF policy per name and include all legitimate senders in that policy.
DKIM: type TXT, name default._domainkey in our lab, content copied in full from our domain's aaPanel screen. Your selector may differ. Copy the complete v=DKIM1 value, without the Copy button label. This publishes a public key; the private signing key stays on the server.
Replace the report mailbox with an address you control. For a domain with existing senders, start by assessing alignment and a monitoring policy before enforcing quarantine/reject.
Our SMTP hostname also received a separate TXT SPF record at mail:
Code:
v=spf1 ip4:YOUR_VPS_IPV4 -all
This describes the HELO hostname's permitted sender; it does not replace the root-domain SPF record.
5. Verify public resolution
Check A, MX and each TXT name through a public DNS resolver. Then return to aaPanel and use Already set, Verify domain name resolution. aaPanel can temporarily display a cached Not Set result; check actual public DNS before changing correct records again.
What comes next
Create the mailbox and mail TLS certificate. PTR/reverse DNS belongs to the VPS provider, not this Cloudflare zone. Finally send a real test message: published records alone do not prove SPF/DKIM/DMARC pass on an actual message.