Perfex CRM SMTP Not Working: Fixing Outgoing Mail
Perfex CRM SMTP not working? Test from the shell, then PHP, then the CRM. Ports, TLS mismatches, app passwords and the queue nobody drains - fixed in order.
You click Send Test Email, the spinner turns over for fifteen seconds, and a red toast appears with no detail in it. Nothing arrives. Nothing lands in spam either, because nothing was ever handed to a mail server. Perfex CRM SMTP not working is a failure people burn afternoons on in the wrong place, because the settings screen looks like the obvious suspect.
It usually is not. The CRM is a PHP application asking the OS to open a TCP socket to somebody else’s mail server. When that request never completes, editing the SMTP password cannot help. Eliminate layers in a fixed order: the shell first, then PHP, then Perfex. The first layer that refuses to talk owns your problem.
We build and sell Perfex modules, two of which are named below, so weigh what follows accordingly. The elimination order works on a stock install with nothing of ours on it.
Separate “not sending” from “not arriving” first
These are opposite failures sharing almost no causes.
- Not sending. The message never leaves your server: the test fails, no bounce arrives, and the provider has no record of it. A transport problem - ports, TLS, credentials, PHP.
- Not arriving. The send succeeds, the provider logs it, and the recipient finds it in junk. That is deliverability - SPF, DKIM, DMARC, reputation - and nothing below touches it.
The cleanest test: open the sending mailbox’s own webmail and look in Sent, or check your relay’s outbound log. If the message is not there, it never left. Everything below assumes it never left.
Test from the shell before you touch the CRM
Get an SSH session on the box that runs Perfex. Not your laptop - your ISP and a datacentre see very different internets, and that difference is the point.
Start with raw reachability on all three candidate ports:
for p in 25 465 587; do
timeout 5 bash -c "cat < /dev/null > /dev/tcp/smtp.example.com/$p" \
&& echo "$p open" || echo "$p BLOCKED"
done
A hang and BLOCKED on every port means an egress firewall, not a Perfex problem. Shared hosts and most cloud providers block outbound 25 by default and never mention it; some block 465 and 587 too until you raise a ticket. That is anti-spam policy, not an application-side fix.
If a port is open, negotiate a real session on it, so you test TLS and credentials in the same breath:
# 587, upgraded in-session
openssl s_client -starttls smtp -crlf -connect smtp.example.com:587
# 465, encrypted from the first byte
openssl s_client -crlf -connect smtp.example.com:465
A working server answers 220, and EHLO yourdomain.com returns a capability list containing AUTH LOGIN PLAIN and, on 587, STARTTLS. If AUTH is absent, that server will never accept credentials on that port, whatever you type into the CRM.
Now test the credentials, before blaming the application. Base64-encode username and password (printf '%s' '[email protected]' | base64), send AUTH LOGIN inside the session, and paste each on its own line. 235 Authentication successful means transport and credentials are fine and the problem lives above this layer. 535 means the credentials are - and on Gmail and Microsoft 365 that is expected rather than surprising.
Perfex CRM SMTP port 465 or 587, and the encryption that must match
This is the most common cause of a Perfex CRM test email failed message on a server where the port is genuinely open. Port and encryption are not independent choices. Pick them as a pair.
| Port | Encryption in Perfex | How the session starts | Use it when |
|---|---|---|---|
| 587 | tls | Plaintext, upgraded by STARTTLS | Modern default |
| 465 | ssl | Encrypted from the first byte | Provider documents 465 |
| 2525 | tls | Same as 587 | 587 fallback |
| 25 | none or tls | Server-to-server relay | Almost never from a CRM |
Set ssl on port 587 and the client opens a TLS handshake against a server expecting plaintext: the connection stalls until the timeout expires - your fifteen-second spinner. Set tls on 465 and the server sends encrypted bytes to a client reading them as text, usually surfacing as a parse error or empty response. Neither names the real cause.
These fields live under Setup > Settings > Email: Email Protocol set to SMTP, then SMTP Host, SMTP Port, SMTP Encryption, Email, SMTP Username and SMTP Password. Two details cause quiet failures:
SMTP Usernameis very often the full email address, not the local part. Providers differ. Use whatever yourAUTH LOGINtest accepted, verbatim.SMTP Hostmust be the submission hostname, not your own domain.mail.yourdomain.compointing at your web server is not a mail server, and fails in a way that looks like bad credentials.
Gmail and Microsoft 365 will not accept your account password
If the shell test returned 535 against Gmail or Microsoft 365, nothing is broken. Basic authentication with an ordinary user password is switched off on both platforms and has been for some time.
Gmail and Google Workspace. Enable 2-Step Verification on the sending account, generate a 16-character app password, and paste it into SMTP Password with the spaces removed. Host smtp.gmail.com, port 587, encryption tls. The constraint people hit a week later: the app password dies if 2-Step Verification is turned off, and it is unavailable where a Workspace administrator has restricted app passwords at domain level. Then a transactional relay beats the policy argument.
Microsoft 365. SMTP AUTH is disabled per-mailbox by default on newer tenants and must be enabled by an administrator on that specific mailbox - a tenant-wide setting is not enough. Host smtp.office365.com, port 587, encryption tls. Microsoft keeps narrowing basic auth, so treat a working password setup here as temporary.
The honest position on both: OAuth2 is the route that keeps working, and a plain SMTP Password field cannot express it. Our Mailbox module connects Gmail and Outlook over OAuth2 for reading and sending, with tokens encrypted and refreshed automatically before they expire, and Outlook handled through SMTP XOAUTH2 against a single Exchange Online resource. Passwords, where still used, are encrypted with AES-256-CBC before reaching the database. One detail matters diagnostically: Mailbox reports a failed send as Failed rather than Sent.
The queue is switched on and nothing drains it
If the test email sends but real invoice, ticket and reminder emails never go out, stop looking at SMTP. You have a cron problem wearing an email costume.
Perfex can queue outgoing mail instead of sending inline, and the cron job drains the queue. Enable it without a working cron and every message is written to the queue table and left there indefinitely - no error, no bounce, nothing visible in the interface. The test email often still works, because it bypasses the queue.
Check three things in this order:
- Last cron run.
Setup > Settings > Cron Jobshows the timestamp. Hours old, days old or blank is your answer. - The crontab exists and uses the right binary.
crontab -las the correct user. The PHP CLI binary is often not the one your control panel shows for the site. - The queue table is growing. Rows accumulating with no sent timestamp confirms it.
Fix the cron first. Everything scheduled in Perfex is failing for the same reason - overdue reminders, recurring invoices, ticket email import - and you noticed the email symptom first.
When one staff member’s mail sends and another’s does not
On a stock install this cannot happen. Perfex sends every outgoing email through a single, system-wide SMTP configuration, so when it fails it fails for everyone equally. Per-person differences mean you already have per-staff sending, and the diagnosis changes shape.
That is what our Advanced Email System provides: each non-admin staff member gets an independent SMTP account, on a different SMTP server if you want, configured from the Perfex settings area with no coding. It removes the single-sender limitation - and multiplies the number of SMTP accounts that must stay healthy. A real trade-off, not a footnote. Run the shell tests once per account, against its own host, port and credentials. One expired app password becomes a one-person outage rather than a company-wide one: better operationally, far easier to miss.
Two notes if you run Mailbox alongside it. It needs an IMAP-enabled account - POP is not supported - that accepts SSL/TLS from a third-party application, and its background fetch depends on the same cron above. Its sent mail uses Perfex’s own outgoing email settings, so a broken global SMTP configuration breaks sending there too. And if the account enforces two-factor authentication and is not Gmail or Outlook over OAuth2, the mail server refuses the connection.
The run-through, in order
Open a shell on the Perfex server and work down. Stop at the first line that fails - the layers below it are noise until that one is fixed.
- Port reachability on 25, 465 and 587 with the loop above. All blocked means a ticket with your host, not more settings changes.
openssl s_client -starttls smtp -crlf -connect HOST:587, thenEHLO yourdomain.com. ConfirmAUTHis in the capability list, thenAUTH LOGINwith base64 credentials. A535sends you to the app-password or OAuth2 section, not back to the settings screen.php -m | grep -i opensslandphp -i | grep disable_functions, against the CLI and FPM binaries separately - they load differentphp.inifiles more often than anyone expects.- On RHEL, Rocky or AlmaLinux:
getsebool httpd_can_network_connect. Ifoff, runsetsebool -P httpd_can_network_connect 1. - Only now open
Setup > Settings > Emailand make port and encryption agree with the pairing table. - Set
log_thresholdto4inapplication/config/config.php, resend, and read the newest file inapplication/logs/. Revert it afterwards - debug logs grow fast on a busy install.
If step 1 fails and your host will not open the port, do not spend the afternoon negotiating. Point Perfex at a transactional relay on 587 or 2525, verify with step 2, and get on with your day.