Description
Version: v1.7.6 (also reproduced on v1.7.4, v1.7.5)
Browser: Firefox 152.0 (also reproduced on Chrome)
Deployment: OpenShift (container: ghcr.io/bulwarkmail/webmail:latest)
When opening an email that contains an inline remote image (e.g. a sender logo or tracking pixel) whose server is unreachable or slow, the email viewer preview window gets stuck at a placeholder height of approximately 150px. The email body does not render until the browser's TCP connection timeout fires (~60 seconds), at which point the image request fails with a network error and the full email appears.
Root Cause Analysis
Since v1.6.7, the email viewer sandboxes email HTML inside a srcDoc iframe with a CSP meta tag for security. The render pipeline appears to wait for the iframe's onload event or a Promise.all over image resource loads before marking the preview as complete and expanding the container from its placeholder height. When an image fetch hangs indefinitely, that signal never fires.
Network Evidence
Below is a captured hanging request from Firefox's Network tab (redacted):
GET /LogoTechnophile-72dpi.png
Host: technophile.services
Status: (pending) -- stalled for ~60s until timeout
Sec-Fetch-Dest: image
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: same-site
The request hangs for ~60 seconds before failing. The email viewer renders immediately after the failure.
Related Changelog Entries
v1.6.7 -- "Sandbox thread email HTML in srcDoc iframe with a CSP tag"
v1.6.3 -- "Redesign external content prompt"
v1.6.0 -- "Respect per-email dark mode toggle when 'always show in light mode' is on"
v1.7.4 -- "Correct dark-mode background-image inversion and height clipping in the email viewer"
Suggested Fix
The email viewer should render the email body independently of external resource loading. Options include:
Fire render-complete on DOMContentLoaded, not on window.load -- This is the most correct fix. The iframe content is available immediately; images should load asynchronously.
Add loading="lazy" to external img elements -- Native lazy loading defers image fetches so they don't block the initial render.
Per-image timeout with fallback -- Set a client-side AbortController timeout of e.g. 10s per image, and hide or replace the broken img with a placeholder on failure.
Always block remote images by default in the sandbox iframe -- Only load images when the user explicitly clicks "Load images" or "Trust sender". This is already the privacy-best practice.
Workaround
In Settings -> Mail, enable "Block remote images" or "Block external content". When remote images are blocked, the preview renders immediately. Trusted senders can be whitelisted per-email via the "Load images" button, and a single failed image there only affects that img tag, not the entire viewer.
Steps to Reproduce
Log into Bulwark Webmail.
Open an email that contains an
tag pointing to an external URL that is either unreachable (server down, DNS failure) or very slow to respond.
Observe the preview pane: it stays at ~150px height with a loading/skeleton state.
Open DevTools -> Network tab.
Observe the image request stuck in "pending" state.
After ~60 seconds (browser timeout), the request fails and the email body renders fully.
Expected Behavior
The email preview should render immediately. External images should load asynchronously in the background. A single hanging image must not block the entire email viewer from displaying.
Actual Behavior
The email viewer holds the render-complete signal until all embedded
resources have either loaded or failed. An image that hangs (server accepts TCP connection but never sends data or closes the connection) blocks the entire preview for the duration of the browser's connection timeout (~60 seconds).
Bulwark Version
1.7.6
Stalwart Mail Server Version
latest
Browser
Firefox
Operating System
Linux
Screenshots / Screen Recording
No response
Relevant Logs or Error Output
Additional Context
No response
Description
Version: v1.7.6 (also reproduced on v1.7.4, v1.7.5)
Browser: Firefox 152.0 (also reproduced on Chrome)
Deployment: OpenShift (container: ghcr.io/bulwarkmail/webmail:latest)
When opening an email that contains an inline remote image (e.g. a sender logo or tracking pixel) whose server is unreachable or slow, the email viewer preview window gets stuck at a placeholder height of approximately 150px. The email body does not render until the browser's TCP connection timeout fires (~60 seconds), at which point the image request fails with a network error and the full email appears.
Root Cause Analysis
Since v1.6.7, the email viewer sandboxes email HTML inside a srcDoc iframe with a CSP meta tag for security. The render pipeline appears to wait for the iframe's onload event or a Promise.all over image resource loads before marking the preview as complete and expanding the container from its placeholder height. When an image fetch hangs indefinitely, that signal never fires.
Network Evidence
Below is a captured hanging request from Firefox's Network tab (redacted):
GET /LogoTechnophile-72dpi.png
Host: technophile.services
Status: (pending) -- stalled for ~60s until timeout
Sec-Fetch-Dest: image
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: same-site
The request hangs for ~60 seconds before failing. The email viewer renders immediately after the failure.
Related Changelog Entries
Suggested Fix
The email viewer should render the email body independently of external resource loading. Options include:
Workaround
In Settings -> Mail, enable "Block remote images" or "Block external content". When remote images are blocked, the preview renders immediately. Trusted senders can be whitelisted per-email via the "Load images" button, and a single failed image there only affects that img tag, not the entire viewer.
Steps to Reproduce
Log into Bulwark Webmail.
tag pointing to an external URL that is either unreachable (server down, DNS failure) or very slow to respond.
Open an email that contains an
Observe the preview pane: it stays at ~150px height with a loading/skeleton state.
Open DevTools -> Network tab.
Observe the image request stuck in "pending" state.
After ~60 seconds (browser timeout), the request fails and the email body renders fully.
Expected Behavior
The email preview should render immediately. External images should load asynchronously in the background. A single hanging image must not block the entire email viewer from displaying.
Actual Behavior
The email viewer holds the render-complete signal until all embedded
resources have either loaded or failed. An image that hangs (server accepts TCP connection but never sends data or closes the connection) blocks the entire preview for the duration of the browser's connection timeout (~60 seconds).
Bulwark Version
1.7.6
Stalwart Mail Server Version
latest
Browser
Firefox
Operating System
Linux
Screenshots / Screen Recording
No response
Relevant Logs or Error Output
Additional Context
No response