# Images in an email do not load

Remote pictures are fetched through Connect's own proxy rather than by your browser, so opening a message tells the sender nothing. A picture that does not appear usually means the remote host refused the proxy, the file needs a sign-in, the link is dead, or the picture was a tracking beacon that the renderer removed on purpose.

- **Status:** Available
- **Audience:** both
- **Channels:** email
- **In the app:** #/inbox
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/troubleshooting/images-not-loading/

## What the symptom looks like

- A message with an obvious gap where a logo, a banner or a signature graphic should be.
- A picture that appears in the same message when you open it at the provider.
- A newsletter that renders as text with every graphic missing.
- A one-pixel gap you would never have noticed — that one is a tracking beacon and its absence is the feature.

Text, links, tables and attachments are unaffected. If the words are wrong as well as the pictures, the question is a different one: [the email renders badly](/docs/troubleshooting/html-looks-wrong/).

## The proxy, and why it is the default

A remote picture in an email is a request from your browser to a server the sender chose. Made directly, that request tells the sender you opened the message, roughly when, and from where. Connect fetches those resources through its own proxy instead, so the sender's server sees a request from Connect and learns nothing about the reader.

This is a privacy default rather than a per-message convenience, and it is the reason a picture can be missing here while it appears at the provider: the provider's client made the request from your browser and Connect did not. The trade is deliberate — a missing logo costs a moment's inconvenience, and a read receipt the reader never agreed to costs something that cannot be taken back.

## Five causes, and what to do about each

| Cause | What you see | What changes | What can fail |
|---|---|---|---|
| The remote host refused the proxy | One sender's graphics are always missing | Nothing; the message is unaffected | Nothing you can change from here — the sender's server decided |
| The file needs a sign-in | A broken graphic from a document or design tool | Nothing | Expecting the proxy to authenticate as you; it cannot and should not |
| The link is dead | An old newsletter with nothing left in it | Nothing | Diagnosing a dead link as a Connect fault — check the same message at the provider |
| It was a tracking beacon | A gap you would not otherwise notice | Nothing, deliberately | Nothing: this is the renderer doing its job |
| It was an attachment shown inline | A graphic referenced by the message rather than fetched | Nothing about the proxy applies | Looking for a network cause when the file simply came with the message |

## The path a picture takes

1. Trigger — you open a message that references a remote resource.
2. External event — the resource lives on a server the sender controls.
3. Authentication and workspace resolution — the message belongs to your workspace, and so does the request made on its behalf.
4. Ingest — `mail_render.py` sanitises the message body and rewrites remote references to the proxy.
5. Canonical record — the message itself is unchanged; rendering is a view, not a rewrite of what arrived.
6. Classification — active content is stripped, and remote resources are separated from anything that came with the message.
7. Knowledge, memory and rules — none of this touches what Connect knows; it is a rendering decision.
8. Autonomy and approval — not involved. Reading a message is not an action that needs permission.
9. Action through a provider — the proxy requests the resource on Connect's own account.
10. Result — the picture appears, or it does not and the message reads as text.
11. Relationship, timeline and memory — unaffected either way.
12. Audit, usage and Needs You — nothing is queued: a missing graphic is not a problem a person must decide about.

## What Connect did complete

- The message was fetched, bridged and rendered in full — every word of it is present.
- Attachments arrived with the message and are available regardless of any remote resource.
- The body was sanitised before it reached your screen.
- No request was made from your browser to the sender's server, which is the point of the design.

## What Connect did not complete

- It did not fetch a resource that the remote host refused to serve to the proxy.
- It did not sign in on your behalf to retrieve a file behind an account.
- It did not restore a beacon it removed, and it will not.
- It did not alter the stored message; the original markup is exactly as it arrived.

## What you can do, and when to escalate

1. Open the same message at the provider if you genuinely need to see the graphic.
   - Result: You have then chosen to make the request yourself, with the tracking consequence that carries.
2. Ask a regular sender to attach graphics rather than link to them.
   - Result: An attached picture is part of the message and needs no remote fetch at all.
3. Check whether the text of the message is complete before spending time on the pictures.
   - Result: In almost every case the content you need is the text, and the graphic is decoration.

An administrator can confirm whether one sender's resources are consistently unavailable, which points at that sender's server rather than at the workspace. Escalate when every picture from every sender is missing at once — one sender failing is normal, all of them failing is not.

## Questions

### Can the sender tell I opened the message?

Not from a remote resource. Fetching through the proxy is what prevents it, and it is the reason a beacon in a message tells the sender nothing useful.

### Is a missing picture a sign the message was tampered with?

No. The stored message is unchanged; what you see is a rendered view of it. The original markup arrived intact and stays that way.

### Why does the same message look complete in Gmail?

Because that client fetched the resources directly from your browser. The difference in appearance is the difference in who made the request.

## Related

- [Remote images in email](https://connectbyjbrh.com/docs/email/remote-images/)
- [Rendering HTML email safely](https://connectbyjbrh.com/docs/email/html-email/)
- [The email renders badly](https://connectbyjbrh.com/docs/troubleshooting/html-looks-wrong/)
- [Email attachments](https://connectbyjbrh.com/docs/email/attachments/)
- [Security and isolation](https://connectbyjbrh.com/docs/security/)
- [Inbound email, end to end](https://connectbyjbrh.com/docs/workflows/inbound-email/)

## What this page is based on

- Connect source pack — channels, §1 rendering and privacy: aggressive sanitising and proxied remote images (`docs-source/sources/CHANNELS.md`)
- Connect source pack — security and the isolation layers (`docs-source/sources/GENERAL.md` §10)
- Connect capability registry (`docs-source/facts.py`) — `html_mail_render`
