Gravity SMTP 2.3.3 fixes a fatal error when attachment headers arrive as a string. The source may be a form notification, invoice plugin, PDF generator, custom wp_mail call, or another integration. A fixed fatal does not prove that filenames, MIME types, message logs, retries, and delivered files remain correct.
Use this when WordPress email fails only with attachments, PHP logs mention attachment headers, or messages are logged without reaching the provider or inbox.
Quick answer
Capture one failing message on staging before changing the producer. Record the exact header type, filename, path, MIME type, size, recipient, message marker, and provider. Update Gravity SMTP to 2.3.3 and send fixtures with one string header, one array header, mixed attachments, Unicode filenames, missing files, zero-byte files, and files near provider limits. Verify one WordPress log record, one provider message ID, one inbox message, and matching attachment checksums. Confirm a fatal or timeout cannot trigger duplicate delivery.
Test scenarios to run
Run the same controlled fixture across these branches. Write down the expected result before testing so a surprising response is easy to identify.
| Scenario | Fixture | Expected result |
| String header | One PDF | One delivered attachment |
| Mixed headers | PDF and image | Both names preserved |
| Missing file | Unreadable path | Clear failure, no send |
| Lost response | Provider accepted | No duplicate retry |
Diagnostic table
Use this table to connect the observed behavior to evidence and a verification step.
| Action | Evidence | Verification |
| Capture the real producer shape | Record Gravity SMTP, PHP, mail producer, connector, provider region, message marker, header value type, file path, filename encoding, MIME type, size, and retry owner. | String and array attachment headers no longer cause a PHP fatal. |
| Update to Gravity SMTP 2.3.3 | Reproduce with one attachment, multiple attachments, string and array headers, Unicode and long filenames, duplicate names, missing path, unreadable file, zero-byte file, and size boundary. | The Gravity SMTP log, provider message, inbox source, and downloaded files agree. |
| Run the attachment matrix | Compare PHP error log, WordPress debug log, Gravity SMTP event and email logs, generated MIME boundaries, provider response, inbox source, and downloaded attachment checksum. | Invalid paths fail clearly without a partial or misleading delivered message. |
| Reconcile provider and inbox evidence | Trigger a failure before provider acceptance and another after provider acceptance, then verify the retry system can distinguish them through message or business identifiers. | Retries use durable evidence to avoid resending a provider-accepted message. |
What to check first
- Record Gravity SMTP, PHP, mail producer, connector, provider region, message marker, header value type, file path, filename encoding, MIME type, size, and retry owner.
- Reproduce with one attachment, multiple attachments, string and array headers, Unicode and long filenames, duplicate names, missing path, unreadable file, zero-byte file, and size boundary.
- Compare PHP error log, WordPress debug log, Gravity SMTP event and email logs, generated MIME boundaries, provider response, inbox source, and downloaded attachment checksum.
- Trigger a failure before provider acceptance and another after provider acceptance, then verify the retry system can distinguish them through message or business identifiers.
- Remove temporary files and test records only after confirming no queued job, webhook, backup connector, or recipient retry still references them.
Field notes
- Write the pass condition before changing anything. A repeatable synthetic fixture makes the before and after comparison useful.
- Keep exact versions and UTC timestamps because scheduled jobs, caches, retries, and background processing can change the evidence.
- Check the public experience and the stored server-side result. Admin previews and isolated API calls do not prove the whole workflow.
- Repeat the test after the relevant cache, queue, scheduled action, webhook, and observation window has finished.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
message_marker: SMTP-ATTACH-20260908-041
header_shape: string
attachments:
- path: /tmp/invoice-041.pdf
sha256: record-value
expected_delivery_count: 1
Why this usually happens
- A producer follows a valid wp_mail pattern that differs from the SMTP plugin’s expected internal type.
- The fatal happens after an email record is created but before the provider response is stored.
- Filename encoding or header folding changes the visible attachment name.
- A general job retry resends a message that the provider already accepted.
Decision rule
Close the incident only when the original string-header producer sends once without a fatal, every intended attachment matches by name and checksum, and failed or lost responses cannot create duplicate mail.
Production verification checklist
- String and array attachment headers no longer cause a PHP fatal.
- The Gravity SMTP log, provider message, inbox source, and downloaded files agree.
- Invalid paths fail clearly without a partial or misleading delivered message.
- Retries use durable evidence to avoid resending a provider-accepted message.
Safe fix order
Use a sequence that makes each result easy to prove. Stop when new evidence changes the scope or owner of the problem.
- Capture the real producer shape
- Update to Gravity SMTP 2.3.3
- Run the attachment matrix
- Reconcile provider and inbox evidence
- Harden duplicate prevention
Mistakes to avoid
- Changing production before recording exact versions, UTC time, the affected fixture, current behavior, and a tested rollback point.
- Accepting one successful admin screen while the public page, stored record, API response, accessibility tree, queue, email, or downstream system remains unchecked.
- Testing only as an administrator instead of the role, browser, device, locale, network state, and failure path that a real customer reaches.
- Leaving broad credentials, debug logs, temporary filters, synthetic records, or recovery code active after verification.
Questions teams ask during testing
Should I test this on production?
Use production for read-only evidence first. Reproduce the change on staging with a current data shape, theme, extensions, cache, and browser mix. If a production canary is necessary, make it reversible, identifiable, monitored, and unable to charge a customer or expose personal data.
How do I rule out a cache artifact?
Record the origin response, purge only affected paths, and repeat in private and normal sessions. Compare stored data and server logs with the visible page. A cache hit is useful evidence only when you know which version it contains.
What belongs in the evidence packet?
Keep UTC time, exact versions, fixture ID, role, browser, expected result, actual result, relevant response or log lines, change made, rollback point, owner, and final verification. Redact passwords, tokens, personal data, and private URLs.
When is the test complete?
Close it when the main path and important failure branches pass, records reconcile across systems, accessibility and mobile checks are complete, temporary changes are removed, and monitoring covers the next update or business cycle.
What to tell the client or owner
Give the owner a short packet with the affected workflow, exact versions, UTC test time, fixture ID, expected result, actual result, key evidence, change made, rollback point, unresolved risk, owner, and next review date. Remove credentials and personal data before sharing it.
When HandL WP should help
Bring in help when this affects leads, checkout, search visibility, security, paid media reporting, or a client production site. HandL WP can trace the issue through WordPress, hosting, cache, tracking, and Search Console, then verify the workflow after the technical fix.
If this is active on a production site, have HandL WP trace WordPress email delivery.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Verify support staff can find the final mail record
After delivery is stable, use the Gravity SMTP 2.3.3 search character-loss regression test to confirm rapid typing, paste, IME input, filters, and out-of-order responses still show the intended email-log record.
Helpful references