sj26/mailcatcher · error

Error receiving message

Error message

Error receiving message

What it means

The SMTP server's receive_message (smtp.rb:57-67) finished the DATA phase and tried to store the message via MailCatcher::Mail.add_message and prune old messages; something in that path raised, the rescue caught it, logged this report with the half-built @current_message as context, and returned false — which makes the EventMachine SMTP server report a delivery error to the sending client. The message is lost from MailCatcher's UI, but the process stays up.

Source

Thrown at lib/mail_catcher/smtp.rb:63

  end

  def receive_data_chunk(lines)
    current_message[:source] ||= +""

    lines.each do |line|
      current_message[:source] << line << "\r\n"
    end

    true
  end

  def receive_message
    MailCatcher::Mail.add_message current_message
    MailCatcher::Mail.delete_older_messages!
    puts "==> SMTP: Received message from '#{current_message[:sender]}' (#{current_message[:source].length} bytes)"
    true
  rescue => exception
    MailCatcher.log_exception("Error receiving message", @current_message, exception)
    false
  ensure
    @current_message = nil
  end
end

View on GitHub (pinned to 18a9cb7a79)

Solutions

  1. Run `mailcatcher --foreground --verbose` and send one failing message; read the `Exception:` line of the printed block to identify the real error.
  2. If it is sqlite3-related (null byte / argument errors), pin a compatible sqlite3 (`gem install sqlite3 -v 1.3.13`) or upgrade mailcatcher to the latest release whose gem constraints are compatible.
  3. If it is Mail/MIME parsing, capture the failing source (context line shows sender/recipients; re-send the same mail to a file with a catch-all like `nc -l 1025`) and fix the sending side's encoding/headers.
  4. If you use --messages-limit, try disabling it to rule out delete_older_messages! as the raiser.
  5. If it reproduces on the latest version with a valid email, file an issue with the full block.

Example fix

# before
mailcatcher   # daemonized; failures vanish after "Error receiving message"

# after: visible triage + compatible sqlite3
mailcatcher --foreground --verbose
gem uninstall sqlite3
gem install sqlite3 -v 1.3.13   # or: gem update mailcatcher
Defensive patterns

Strategy: try-catch

Validate before calling

# Sanity-check a message before handing the SMTP path a pathological payload
# (guards the two known raisers: SQLite3 insert and Mail MIME parsing)
def safe_to_send?(raw_source)
  raw_source.is_a?(String) &&
    !raw_source.include?("\0") && # null bytes break older sqlite3 inserts
    raw_source.valid_encoding? &&
    raw_source.each_line.none? { |l| l.bytesize > 998 } rescue false
end

abort "refusing to send malformed mail" unless safe_to_send?(mail_source)

Type guard

# Narrow to the hash shape receive_message expects before injecting into MailCatcher::Mail
def valid_message_hash?(msg)
  msg.is_a?(Hash) && msg.key?(:sender) && msg[:sender].is_a?(String) &&
    msg[:recipients].is_a?(Array) && msg[:source].is_a?(String) && !msg[:source].empty?
end

Try / catch

# receive_message already rescues and returns false; embedders should mirror that contract
begin
  MailCatcher::Mail.add_message(current_message)
rescue => e
  MailCatcher.log_exception("Error receiving message", current_message, e)
  false # SMTP-equivalent: tell the client this delivery failed, keep serving
end

Prevention

When it happens

Trigger: A SMTP client completes MAIL FROM/RCPT TO/DATA for a message whose source then fails to parse (Mail.new in mail.rb:47 raising on malformed MIME/encoding) or fails to persist (SQLite3 insert errors in mail.rb:45-67, e.g. null bytes in the source with newer sqlite3 gems, or a prepared-statement type mismatch). Also fires if delete_older_messages! raises while honoring --messages-limit.

Common situations: ActionMailer/Rails apps sending 8-bit or malformed headers; upgrading the sqlite3 gem (1.3 -> 1.4+) under an old mailcatcher, producing ArgumentError/SQLite3 errors on insert; unusual attachments (embedded null bytes, odd charsets); automated test suites that send hand-rolled raw SMTP payloads.

Related errors


AI-assisted analysis of sj26/mailcatcher@18a9cb7a79 (2026-08-21). Data as JSON: /api/errors/488419ae346291f2. Report an issue: GitHub.