Troubleshooting
Start in the console. Every mail carries its current state, every send attempt with the provider’s exact response, and the full SMTP transcript of the ingest conversation. Usually the answer is on the mail’s page; this guide maps what you see there to a cause and a fix.
Find your symptom below (the literal error codes are in the headings, so
Ctrl-F for the one you’re staring at). Every entry names the Cause.
and the Fix.
Connecting and authenticating
Section titled “Connecting and authenticating”AUTH is rejected with 535 Authentication failed
Section titled “AUTH is rejected with 535 Authentication failed”Cause. Mailway answers 535 5.7.8 Authentication failed: the username
and password don’t match an active SMTP credential. Usually one of these: a typo or a truncated paste, a
credential that was revoked, the username of one credential with the
password of another, or an API key (mw_live_…) pasted where the
password belongs. 535 is permanent: your mailer won’t retry it.
Fix. Open the project’s page in the console, go to its Access
section, and check that the credential is still listed. Reveal its
password there and paste the username (mw_user_…) and password
(mw_pass_…) again. If the credential was revoked, create a new one
with New SMTP credential.
A mail is refused with 530 (credential revoked)
Section titled “A mail is refused with 530 (credential revoked)”Cause. The SMTP credential was revoked while your app’s connection was
still open. Within a minute of the revoke, Mailway refuses the next mail on
that connection with 530 5.7.0 This SMTP credential was revoked. Mail that
Mailway received with it in the 5 minutes after the revoke is still sent.
Mail received later (possible only if Mailway couldn’t check the credential
in time) is kept as Rejected and not sent (mail.failed, reason
smtp_credential_revoked). 530 is permanent: a mail server (Postfix, Exim)
returns the mail to its sender instead of retrying, and an app library
(nodemailer, PHPMailer, Symfony Mailer) reports an error.
Fix. Create a new credential with New SMTP credential in the project’s Access section, switch your app to it, and resend what was refused.
AUTH is rejected with 538
Section titled “AUTH is rejected with 538”Cause. You tried to authenticate on a plaintext connection. Mailway
never accepts credentials in the clear, and answers 538 5.7.11 Encryption required for requested authentication mechanism; send STARTTLS first.
Fix. Negotiate TLS before AUTH — use STARTTLS on a submission
port (587, 25, 2525, 2587, 588) or connect with implicit TLS on 465 or
2465. Most libraries do this automatically once you set the right port and
enable TLS. See the ports table.
The connection times out or is refused
Section titled “The connection times out or is refused”Cause. Your platform is blocking outbound SMTP, not Mailway rejecting you — this is extremely common. GCP blocks outbound port 25 to external destinations. DigitalOcean blocks 25, 465, and 587 by default. AWS blocks 25 by default.
Fix. Try another port — Mailway listens on seven for this exact reason (587 → 2525 → 2587 → 588, or 465 → 2465). Same host, same credentials. Whatever your network lets out, one gets through.
The connection hangs only over IPv6
Section titled “The connection hangs only over IPv6”Cause. smtp.mailway.net has an IPv6 address as well as an IPv4 one,
and a system with IPv6 usually tries it first. Some hosts block a port over
IPv6 even when it works over IPv4. On a DigitalOcean Droplet, 587 can answer
over IPv4 and hang over IPv6. Gmail’s SMTP server hangs there too, so the
block is the host’s, not Mailway’s. To check, run
telnet -4 smtp.mailway.net 587: it shows
220 mailway.net ESMTP Mailway ready, while telnet smtp.mailway.net 587
stops at Trying 2a01:…. Depending on the client, the send fails with a
timeout, or reaches IPv4 only after the IPv6 attempt times out.
Fix. Use an alternate port: 2525, 2587, or 588 for STARTTLS, or 2465 for implicit TLS. On a DigitalOcean Droplet they answer over IPv6 too. Or make your client connect over IPv4.
Auth fails intermittently with 454
Section titled “Auth fails intermittently with 454”Cause. A temporary throttle, not a bad credential — Mailway’s
auth backend was rate-limited or unavailable for a moment. The text is
454 4.7.0 Too many authentication attempts, please retry in a moment or
454 4.7.0 Authentication service temporarily unavailable, please retry in a moment.
Fix. Retry with backoff. Your credential is fine; don’t rotate it. A
persistent 454 on every attempt is worth a support request.
The connection is refused with 421
Section titled “The connection is refused with 421”Cause. Mailway refused the connection, not your mail. 421 is
temporary, and the text says why:
421 4.7.0 Too many SMTP sessions for this team at once, please retry in a moment, in reply toAUTH: your team already has 128 SMTP sessions open at once, counted across all its credentials and projects (16 on the sandbox,smtp.mailway.dev).421 4.7.0 Too many connections from your host, please retry in a moment: one sending host (one IPv4 address, or one IPv6/64) has 128 connections open at once (16 on the sandbox).421 4.7.0 Too many new connections from your host, please retry in a moment: one sending host opened more than 3,000 connections in a minute (120 on the sandbox).421 4.7.0 Too many connected clients, please retry in a moment: the relay as a whole, or the port you use, is at its connection limit. The alternate ports (25,588,2465,2525,2587) take 8 connections each; if your network allows it, use587or465.421 4.7.1 Too many failed authentication attempts from your host, please retry later: 10 authentication attempts from your host failed within 10 minutes. Each failure stops counting 10 minutes after it happened, and a successful authentication clears them all. Check the credential first (see535), or the retries keep the host locked out.421 4.7.1 Your IP address is on a blocklist; …: your sending address is on one of the public lists of abusive addresses that Mailway checks. If that’s wrong, write to hello@mailway.net.
Fix. Retry with backoff. A mail server queues the message and retries
on its own; an app library such as nodemailer, PHPMailer, or Symfony Mailer
reports an error instead, so the retry has to come from your app (see
the 451 fix). If you open a new
connection per message, reuse one connection for several messages instead.
The message is refused with 451
Section titled “The message is refused with 451”Cause. A temporary refusal on Mailway’s side, after your app sent the
message. The text says which: 451 4.3.0 Too much mail in flight, please retry
(the relay is already receiving as much mail at once as it allows, or your
team’s uploads in progress already take a quarter of that), or
451 4.3.0 Temporary local error, nothing was stored, please retry (Mailway
couldn’t store the message), or 451 4.3.0 Temporary local error, please retry at any other step, when something failed inside Mailway. Either way,
Mailway did not receive the message, so nothing was stored and nothing will be sent.
Fix. Retry with backoff. Who retries depends on what sends the mail. A
mail server (Postfix, Exim) keeps the message in its queue and retries on
its own, and the message goes through on a later attempt. An app library
such as nodemailer, PHPMailer, or Symfony Mailer doesn’t: it reports an
error to your code, and the mail is lost unless your app tries again. Send
from a job queue that retries with a delay, for example a queued Laravel
mailable with $tries above 1 and a $backoff.
A sender or recipient is refused with 501 or 550
Section titled “A sender or recipient is refused with 501 or 550”Cause. Mailway checks the envelope addresses (MAIL FROM and
RCPT TO) before your app sends the message, and refuses an address it
can’t relay:
550 5.1.7 Null sender …: the envelope sender is empty (MAIL FROM:<>), which is how bounces and auto-replies are usually sent. Mailway hands each mail to your provider from theMAIL FROMaddress, so a mail without one can’t go out.501 5.1.7 Bad sender address syntaxor501 5.1.3 Bad recipient address syntax: the address isn’t valid. Examples: an unquoted comma, bracket, or colon before the@(a,b@example.com), a domain that starts or ends with a hyphen, or an emoji anywhere in the address.
Fix. Set MAIL FROM to an address on a domain your provider has
verified, and correct any malformed address. A refused recipient doesn’t
stop the mail: Mailway can still receive it for the recipients that got a
250. What happens next depends on your app’s mailer. Some send to the
other recipients and report the refused one; others, Symfony Mailer and
Laravel among them, stop and send nothing.
Mail that doesn’t reach the inbox
Section titled “Mail that doesn’t reach the inbox”A mail is stuck in accepted and never reaches delivered
Section titled “A mail is stuck in accepted and never reaches delivered”Cause. Usually not a problem. accepted means a provider took
the handoff; delivered means the recipient’s server confirmed receipt,
reported back through delivery events. Only providers
that emit those events can ever show delivered — every supported
provider except Gmail / Google Workspace and generic SMTP servers,
once its delivery events are wired up. Those two stop at accepted by
design, and that is not a failure.
Fix. If you want real delivered/bounced signal, use a provider that
reports it and wire up its delivery events (SES: configuration set → SNS;
the others: a webhook pointed at Mailway). The provider’s Delivery
tracking button in the console walks you through it. See the
Amazon SES,
Brevo,
Mailgun,
Mailjet,
MailerSend,
Mailtrap,
Mandrill,
Nuntly,
Postmark,
Resend,
SendGrid and
SMTP2GO guides.
Otherwise, read accepted as “the provider has it.”
A mail shows Rejected (failed)
Section titled “A mail shows Rejected (failed)”Cause. The mail was stopped for good before delivery. The console
labels the failed state Rejected, and the mail’s page says who
stopped it:
- A recipient is on the project’s suppression list — auto-added from an earlier permanent bounce or complaint, or added manually. The send is blocked before it goes out.
- A provider permanently refused a single-recipient send — a hard bounce (bad mailbox, blocked sender) stops the retry chain instead of retrying an address that can’t receive.
- A person or a rule rejected it — for example, a held mail someone chose Reject on.
Fix. Open the mail and read what stopped it. If it’s a suppression you disagree with, un-suppress the address. If it’s a hard bounce, the recipient address is the problem. If the rejection was a mistake, Retry sends it again (Pro and up).
A mail shows exhausted
Section titled “A mail shows exhausted”Cause. Every provider in the project’s chain refused the mail, so
Mailway stopped trying. This is almost always about the provider
accounts, not the recipient: a rotated or revoked API key (535
from the provider), credits or a quota used up, or a billing problem on
every attached account at once. A project with only one provider has no
chain to fall back on.
Fix. Open the mail and read each send attempt: it shows which provider answered and its exact response. Repair the account at that provider (and update its credentials under Providers if you created a new key), then choose Retry on the mail (Pro and up): retrying starts the chain again. To stop one broken account taking every mail down, attach a second provider to the project. Failover is included on Pro and up.
A mail shows paused
Section titled “A mail shows paused”Cause. The mail is held for review: a rule paused it,
the project is paused, or it was sent with "paused": true over the
HTTP API. Nothing is sent until someone releases it.
Fix. Open the mail and choose Release to send it, or Reject to stop it for good. If the whole project is paused, resume the project from its page first. Resuming doesn’t send what the pause held: release those mails one by one, or all at once with Release held mails on the project’s page.
A mail is bounced or soft_bounced
Section titled “A mail is bounced or soft_bounced”Cause. A provider delivery event came back negative. Hard
(bounced) is permanent — the address is invalid or blocking you, and
every address the bounce report names is added to the project’s
suppressions.
Soft (soft_bounced) is transient — a full mailbox, greylisting, a
momentary defer — and the provider keeps retrying.
Fix. Hard bounces mean fix or drop the address. Soft bounces usually
resolve themselves; a persistent one is a receiver-side issue. Filter your
list with state:bounced to review them in bulk.
Mail is authenticated but lands in spam
Section titled “Mail is authenticated but lands in spam”Cause. Authentication passing is necessary, not sufficient — alignment, reputation, and content still decide placement.
Fix. Follow the deliverability guide. The most common BYOK cause is DMARC not aligned to your domain; a Mail Tester score points at the rest.
Quotas and limits
Section titled “Quotas and limits”Sends are blocked with 550 or 452
Section titled “Sends are blocked with 550 or 452”Cause. You’ve hit a plan quota at SMTP time.
550(permanent) — a monthly cap is spent for this billing period: the message quota (Free plan only; every other plan soft-overages past it) or the data-volume limit (any plan, once its grace margin is used). A550can also mean the team is a person’s second Free team: only one Free team per person can send real mail (Limits & quotas). An admin or someone with the Finance role can choose a paid plan for it under Billing in the console. The text starts550 5.7.0 Monthly email limit reached for this plan.,550 5.7.0 Monthly data volume limit reached for this plan.or550 5.7.0 This is a second Free team: ….452(transient) — the Free plan’s daily send limit. It resets at 00:00 UTC; retry after that. The text starts452 4.7.0 Daily send limit reached for this plan.
A 550 whose text starts 5.1.7 Null sender isn’t a quota: see
A sender or recipient is refused.
A 452 4.3.1 Insufficient system storage, please retry later isn’t a quota
either: Mailway’s SMTP relay is short of disk space and refuses new mail
at MAIL FROM until it has room. It is temporary; retry with backoff.
Fix. Check usage against your plan quotas.
The permanent 550 needs a plan change or the month to roll over; the
daily 452 just needs to wait for the reset. (On the HTTP API
the equivalents are 402 and 429 — see Errors.)
A message is rejected with 552
Section titled “A message is rejected with 552”Cause. Mailway answers 552 5.3.4 Message size exceeds the 25 MB limit: the message exceeds the 25 MB SMTP size limit, the same
overall ceiling the HTTP API enforces. (The API is stricter inside it:
html and text are capped at 2 MB each, a single attachment at 10 MB;
see Limits.)
Fix. Shrink it — host large attachments and link them, or split the send. The HTTP API’s attachment caps are listed under Limits.
A message is refused with 554 5.6.0
Section titled “A message is refused with 554 5.6.0”Cause. Mailway read the whole message and won’t relay it as it is. The text says why:
554 5.6.0 Message has no From header field; add one: the message names no author. Mailway can’t pick one for you, and many providers and inboxes refuse such a mail.554 5.6.0 Message contains a NUL byte, which email does not allow; encode binary data as base64.554 5.6.0 Message header contains a bare carriage return; end every header line with CRLF.554 5.6.0 Message header has a line starting with a dot; start every header line with a field name: in SMTP, a line that is only a dot ends the message. Header lines start with a field name such asSubject:, so Mailway refuses a mail whose header has a line that starts with a dot instead of relaying it.
Nothing was stored, and 554 is permanent: a mail server returns the mail
to its sender, and an app library reports an error.
Fix. Add a From: header field naming the author, send binary
attachments base64-encoded (mail libraries do this by default), end every
header line with CRLF, and start every header line with a field name. If
your app builds the message itself, check that an empty line separates the
header from the body: without one, a body line that starts with a dot
counts as a header line. Then send the mail again.
Recipients over 50, or Amazon SES returns 554 … exceeds 50
Section titled “Recipients over 50, or Amazon SES returns 554 … exceeds 50”Cause. SES caps a message at 50 recipients, counting the union of
the SMTP envelope and the To/Cc/Bcc header addresses, evaluated after
DATA — which is why splitting the envelope alone doesn’t fix it. Mailway
handles this for you: above the cap it collapses the visible recipient
headers and fans the send out BCC-style across sub-cap chunks. A raw 554
reaching your app means it came from somewhere Mailway’s fan-out didn’t cover.
Fix. You shouldn’t normally see it on relayed SMTP mail. On the HTTP
API, requests over 50 recipients are rejected up front with 422 — batch
them instead. Full behavior, the live-SES probes, and what changes for your
recipients: 554 Recipient count exceeds
50.
Fidelity and webhooks
Section titled “Fidelity and webhooks”A delivered mail doesn’t match what I sent
Section titled “A delivered mail doesn’t match what I sent”Cause. Most often, the provider changed its copy. For example,
Amazon SES replaces Message-ID and Date, Postmark composes a new
message, and Brevo converts plain text to HTML and adds a tracking pixel.
Each provider’s changes are listed in
What providers change. The other
cause is on Mailway’s side: the message was re-encoded instead of
relayed byte-for-byte. That only happens when SMTP mail goes out through a
provider account that can’t relay it (one limited to a structured-only
API — every provider’s API except Amazon SES’s and Mailgun’s — because
it’s set to Send via: API only or holds only an API key) and an admin has explicitly
enabled re-encoding for that project–provider pair. It’s off by default;
without it, relayed mail skips such an account.
Fix. Check the mail’s fidelity — relayed (Mailway relayed your
app’s message byte-for-byte, apart from the automatic exceptions), constructed (born on the API/console), or
re-encoded. Filter with fidelity:re-encoded to find mail Mailway
rebuilt. For those, set the account’s Send via back to Auto (it
then relays over the provider’s SMTP), use a raw-capable provider (SES,
Mailgun), or leave re-encoding disabled
(SMTP mail through API providers).
For relayed mail, compare the delivered copy with the archived one. The
archived copy already has the changes Mailway makes on receipt (a missing
Message-ID or Date added, a Bcc field removed, line endings sent as
CRLF; see SMTP relay), and above a
provider’s recipient limit Mailway also replaces the visible recipient
headers. Any other difference is the provider’s: check its settings
(tracking, especially).
A webhook isn’t arriving
Section titled “A webhook isn’t arriving”Cause. Your endpoint isn’t accepting the delivery, or the endpoint was auto-disabled after repeated failures.
Fix. Work through these in order:
- Your endpoint must respond 2xx quickly. Non-2xx (or a redirect — Mailway does not follow them) counts as a failure.
- Mailway retries a failed delivery on a backoff ladder and auto-disables an endpoint after 24 hours of continuous failure. Re-enable it in the console once it’s healthy.
- Verify you’re checking the HMAC signature correctly — a signature mismatch is often a raw-body/parsing bug on your side. The verification snippet is on the Webhooks page.
- Delivery is at-least-once — dedupe on
(type, data.mail.uid)so a retry can’t double-process. A “missing” event is sometimes one your handler acknowledged with200and then discarded.
Triage from the mails list
Section titled “Triage from the mails list”The search box on the mails list turns these symptoms into filters. The operators:
| Operator | Example | Finds |
|---|---|---|
state: |
state:failed |
Mail in a lifecycle state (aliases: held, sent, rejected, soft, undeliverable, capture) |
to: / from: |
to:user@example.com |
An exact address or a fragment |
provider: |
provider:amazon-ses |
Mail routed through a provider (its family, or one account’s pv.… id) |
fidelity: |
fidelity:re-encoded |
relayed / constructed / re-encoded |
dkim: |
dkim:fail |
Sender-DKIM verdict on the stored message (pass / fail / none / error / unsupported) |
rescued: |
rescued:yes |
Mail a failover saved (a later provider succeeded) |
after: / before: |
after:2026-07-01 |
A date window (after:D before:D+1 = one day) |
last: |
last:24h |
A rolling window (s/m/h/d/w) |
size: |
size>5mb |
The only operator that takes comparators |
subject: / category: |
subject:invoice |
Subject substring / exact send category |
They combine: state:failed after:2026-07-01, state:soft_bounced provider:amazon-ses,
rescued:yes last:7d.
The state ladder
Section titled “The state ladder”A mail sits in the highest state it has reached. Highest-priority first:
| State | Meaning |
|---|---|
complained |
Recipient marked it as spam (delivery event) |
bounced |
Permanent hard bounce (delivery event) |
delivered |
Recipient’s server confirmed receipt (delivery event) |
soft_bounced |
Transient defer; the provider is retrying |
accepted |
A provider took the handoff — no delivery event yet |
failed |
Stopped for good before delivery (a person, a rule, the suppression list, or a single-recipient hard bounce) — shown as “Rejected” |
exhausted |
Every delivery attempt failed (retries used up) — shown as “Exhausted” |
captured |
Sandbox capture (*.mailway.dev), never forwarded |
paused |
Held (project paused, over daily cap, or awaiting release) |
pending |
Mailway has the mail and is sending it to a provider |
Getting help
Section titled “Getting help”If several things fail at once, check status.mailway.net first: it shows whether Mailway’s SMTP relay, HTTP API, and console are up right now.
If you’re stuck, email hello@mailway.net or use the contact form. A support request moves fastest with:
- the mail ID (
m.01k8w9…) — it threads the whole timeline together, - which send attempt failed and the provider response it shows, and
- the SMTP transcript from the mail detail page, if it’s an ingest issue.
Cookie consent
We may run ads on Google and Reddit. If we do, knowing whether they work needs your OK for one cookie each from them, used only to tie a signup back to the ad that brought it. Analytics here is cookieless either way, and declining changes nothing else.
Change your mind any time with "Cookie choices" in the footer. Details in the privacy policy.