Guides
Troubleshooting
Diagnose connection failures, missing emails, wait timeouts, and cross-test reads.Symptoms first: each section lists checks in the order that most often resolves the problem. All examples assume the default ports; substitute your own if you changed them.
Connection refused
The SDK or curl cannot reach the HTTP API. Either the server is not running, or it started on a
custom --api-port while the client still points at the default. Confirm with:
curl http://localhost:8025/healthIf you changed --api-port, pass a matching baseUrl to InboxTapClient.
Port already in use
Startup fails when another process — often a forgotten InboxTap — already owns 1025 or 8025.
Find it with lsof -i :1025, then stop it, or start InboxTap elsewhere with --smtp-port and
--api-port. When ports change, update both the application's SMTP settings and the client's
baseUrl. The programmatic server sidesteps the problem entirely with smtpPort: 0 and
apiPort: 0.
The email never arrives
Check that the application under test sends to the host and port InboxTap bound — a production SMTP
host left in an env file is the usual cause. The other common cause is a mailer configured for
authentication or TLS: InboxTap deliberately rejects AUTH and STARTTLS, so configure plain
unauthenticated SMTP (for Nodemailer, secure: false and no auth block). See what actually
arrived with an unfiltered list:
curl http://localhost:8025/api/emailsWaits time out
Raise timeoutMs when the flow under test is genuinely slow, but keep it at or below 60000: the
server caps a single wait at 60 seconds and rejects larger values with a 400. Ordering is not the
problem — wait helpers scan already-captured messages before polling, so it is safe to trigger the
email first and wait afterwards. If the wait still expires, check the filter: a string subject
matches as a case-insensitive substring, a regular expression matches its pattern, and a to filter
must exactly match the recipient address.
Tests read each other's messages
Call createInbox() inside every test so each one waits on a unique recipient address. A hard-coded
shared address makes parallel workers consume one another's messages, and no amount of clearing
fixes the race. inbox.clear() deletes only that inbox's messages, so per-test cleanup never
disturbs a parallel worker.
Messages disappear
The store is a bounded FIFO that retains the newest maxMessages (default 100). A busy parallel
suite can evict a message between sending and asserting. Await the value immediately with a wait
helper instead of listing later, or raise the limit with --max-messages.
Message rejected as too large
InboxTap answers SMTP 552 for any message over maxMessageSize (default 5242880 bytes). Large
inline images are the usual culprit. Raise the limit with --max-message-size, or slim the email —
attachments are out of scope for v1.4.1 regardless.