SMTP

CodeIgniter SMTP Mail Not Working

CodeIgniter SMTP fails silently when protocol is left at mail. Set it to smtp, match crypto to port, use correct CI3/CI4 keys, and call print_debugger().

Updated Jul 1, 2026

The short answer

"CodeIgniter SMTP mail not working" is not an SMTP reply code; it is a catch-all for the Email class failing silently or send() returning false. The usual cause is leaving protocol at its default ('mail') so SMTP is never used, plus a wrong host, port, or crypto pairing, wrong CI3-versus-CI4 config keys, or bad auth. Fix it by setting protocol to 'smtp', using the correct snake_case keys in CI3, matching the crypto setting to the port, using a Gmail App Password, and calling print_debugger() after send(false) to read the real error.

Is "CodeIgniter SMTP Mail Not Working" a real SMTP error?

No. There is no SMTP reply code or enhanced status code by this name. It's a generic label for any situation where CodeIgniter's Email class fails to deliver over SMTP — typically $email->send() returning false, a connection timeout, or mail that appears "sent" but is actually being handed to PHP's local mail() function instead of your SMTP server. Because the symptom is generic, the first job is to surface the real underlying error (which often is a standard SMTP code like 535 5.7.8 auth failure or a socket-level connection refusal).

How do I see the actual SMTP error?

CodeIgniter clears the email data after a normal send(), so you must pass false to keep it, then print the debugger:

if (! $this->email->send(false)) { // CI3: send(FALSE) — keep data
echo $this->email->print_debugger(['headers', 'subject', 'body']);
}
// CodeIgniter 4:
// if (! $email->send(false)) { echo $email->printDebugger(['headers']); }

This prints the SMTP conversation and the server's reply (e.g. 535 5.7.8 Username and Password not accepted, Failed to connect to server, STARTTLS failed). Diagnose from that reply rather than guessing. (CodeIgniter Email Class docs.)

What causes CodeIgniter SMTP mail to fail?

  • protocol left at the default. CodeIgniter's Email class defaults protocol to mail (the PHP mail() function) — not smtp. If you never set the protocol to smtp, your SMTP host/user/pass are ignored and PHP tries the local mailer, which silently does nothing on most servers. This is the single most common cause.
  • Wrong config key names for your CI version. CodeIgniter 3 and CodeIgniter 4 use different key names, and a key the framework doesn't recognize is silently ignored — producing the same symptom as not configuring SMTP at all. CI3 uses snake_case keys (protocol, smtp_host, smtp_user, smtp_pass, smtp_port, smtp_crypto, smtp_timeout, mailtype). CI4 uses camelCase/property-style names (protocol, SMTPHost, SMTPUser, SMTPPass, SMTPPort, SMTPCrypto, SMTPTimeout, mailType). Don't mix them.
  • Port and crypto setting don't match. Per RFC 8314, port 465 is implicit TLS (the channel is encrypted from the start — CodeIgniter's own docs say to set SMTPCrypto/smtp_crypto to an empty string ('') for port 465, since STARTTLS is not needed), and port 587 uses STARTTLS (use tls). Pairing 465 with 'tls', or 587 with an empty/implicit-SSL setting, causes a handshake/STARTTLS failure. Both 465 and 587 are valid and current — neither is deprecated.
  • Authentication rejected (535 5.7.8). Wrong username/password, or — for Gmail/Google Workspace — using your normal account password. Google removed "Less Secure Apps" (personal accounts on May 30, 2022; Workspace phased out after), so you must use an App Password (requires 2-Step Verification) or OAuth 2.0. Do not look for a "less secure apps" toggle — that setting no longer exists.
  • Outbound port blocked. Many shared hosts firewall outbound 25/465/587. A timeout / "failed to connect" in the debugger points here — confirm with telnet smtp.host 587 from the server and ask the host to open the port or use an API-based sender.
  • Broken line endings. newline/crlf must be the real escape sequence "\r\n" to comply with RFC 5322. A literal "/r/n" (forward slashes, as in many copy-pasted snippets) produces malformed headers and rejected or garbled mail. Note that escape sequences are interpreted in double quotes but treated literally in single quotes — a single-quoted '\r\n' is not a real CRLF.

How do I fix it (CodeIgniter 3)?

In CI3, use the snake_case keys, set protocol to smtp, match the crypto to the port, use real \r\n, and use an App Password for Gmail:

$config = [
'protocol' => 'smtp', // REQUIRED — without this, SMTP is never used
'smtp_host' => 'smtp.gmail.com',
'smtp_user' => 'you@gmail.com',
'smtp_pass' => 'your-16-char-app-password', // NOT your login password
'smtp_port' => 587, // 587 -> STARTTLS
'smtp_crypto' => 'tls', // use '' (empty string) for port 465 (implicit TLS)
'smtp_timeout' => 30,
'mailtype' => 'html',
'charset' => 'utf-8',
'newline' => "\r\n", // real CRLF, double quotes — RFC 5322
'crlf' => "\r\n",
];
$this->load->library('email');
$this->email->initialize($config);
$this->email->from('you@gmail.com', 'Your App');
$this->email->to('recipient@example.com');
$this->email->subject('Test');
$this->email->message('<p>Hello from CodeIgniter</p>');
if (! $this->email->send(false)) {
log_message('error', $this->email->print_debugger(['headers']));
}

Note: in CI3 the keys are lowercase snake_case (smtp_host, smtp_crypto, smtp_port, ...). Using the CI4-style SMTPHost/SMTPCrypto names here is a common mistake — CI3 silently ignores unrecognized keys, so SMTP never gets configured and the send falls back to the default mail protocol.

CodeIgniter 4 specifics

In CI4, configure app/Config/Email.php (or pass an array to \Config\Services::email()), then $email->send() / $email->printDebugger(). The concepts (protocol => 'smtp', host, port/crypto pairing, App Password) are the same, but the key names differ from CI3: CI4 uses SMTPHost, SMTPUser, SMTPPass, SMTPPort, SMTPCrypto, SMTPTimeout, and mailType. Don't copy CI3 snake_case keys into a CI4 config or vice-versa.

Still failing?

If the debugger shows a clean SMTP 250 accept but mail never arrives, the problem has moved downstream to deliverability — SPF/DKIM/DMARC alignment, the sending IP's reputation, or spam filtering — not CodeIgniter. Sending through a dedicated provider (or a notifications API such as Courier) over an authenticated API instead of raw SMTP sidesteps host port-blocking and gives you delivery logs to diagnose the rest.

FAQ

Common questions

Most often because protocol was left at its default ('mail'/'sendmail') instead of 'smtp', so CodeIgniter handed the message to PHP's local mailer, which silently discards it on servers without a configured MTA. Set protocol => 'smtp' and re-test with send(false) + printDebugger(). If SMTP returns 250 but mail still doesn't arrive, the issue is deliverability (SPF/DKIM/DMARC or spam filtering), not CodeIgniter.

One API, every provider

Stop debugging raw provider errors

Courier connects to your email, SMS, and push providers, handles retries and failover, and surfaces delivery errors in plain language.

Reply-code definitions per RFC 8314 §3.3 (implicit TLS / port 465 vs 587); RFC 5322 (CRLF line endings). Last reviewed Jul 1, 2026. Courier is not affiliated with third-party providers; error behavior may vary by implementation.