ℹ Disclaimer: Content may contain affiliate links, WPThink.com may earn a commission from qualifying purchases.
Static Export Missing Images? Here’s Where It Usually Breaks
When images disappear after export, the real bug is usually classification, not rendering.
The build finishes, the HTML opens, and every chart, logo, or hero image turns into a blank box. That pattern rarely points to one bad file. It usually means the failure happened in a specific layer: the asset was never emitted, the URL was rewritten incorrectly, the host serves the wrong path, or the browser requests a file that exists only in development.
The fastest progress comes from sorting the symptom before touching config. An image missing from the export directory is a build-time problem. A file present on disk but returning 404 is a routing or base-path problem. A correct URL that still fails can indicate case-sensitive filenames, unsupported optimization during static export, or MIME and caching issues at the host. SAME symptom on the page; very different causes underneath.
- Missing from out/ or dist/: asset generation/import pipeline failed.
- Present in export, broken in browser: path rewriting, basePath, or CDN prefix issue.
- Works locally, fails after deploy: case sensitivity or host-specific static file rules.
First check: did the files get exported?
Before debugging paths, confirm that the export actually emitted image files. Open the generated output and look for expected /uploads/, /media/, or hashed asset directories. If those files are absent, the failure happened before URL rewriting or hosting ever entered the picture.
Build logs usually expose the real cause. Search for skipped downloads, 401/403 responses, remote fetch retries, storage adapter errors, or jobs cut short by memory and time limits. This shows up often when a WordPress static export times out, leaving HTML behind but only part of the media copied.
Common reasons the files never arrive:
- Offloaded media lives in S3, Cloudinary, or another origin the exporter never crawled.
- Private media sources require cookies, signed URLs, VPN access, or Basic Auth during the build.
- Partial builds reuse stale caches and skip missing assets.
- Interrupted jobs complete page generation before media sync finishes.
Frontend inspection can mislead. Pages may reference perfectly valid image paths while the exported directory is empty, so artifact inspection should come before browser-side debugging.
When exported files still 404
A surprising number of post-export image failures happen after generation succeeds. The file is present in /wp-content/uploads/, but the browser requests a different URL than the host actually serves.
Where the mismatch appears
Common breakpoints include:
- Base URL drift: export embeds
https://example.com, while production runs athttps://www.example.comor another domain. - Subdirectory confusion: assets are written for
/blog/wp-content/..., but the site is deployed at/or vice versa. - Path normalization changes: one layer collapses duplicate slashes, strips trailing slashes, lowercases paths, or decodes
%20differently. - CDN or proxy rewrites: HTML points to an origin path the edge does not map.
What to compare
Check three values side by side:
- The image URL inside the exported HTML.
- The actual deployed file path.
- The public route the host exposes.
If any segment differs, requests fail despite valid files. This is especially common when WordPress siteurl, home URL, and static host base path were not aligned before export.
When only the homepage loads images
A homepage that renders every image correctly while deeper pages fail is rarely a missing-file problem. It usually means the asset URL is relative to the current document, so each nested route adds another directory level.
For example, <img src="images/logo.svg"> works at /index.html because it resolves to /images/logo.svg. The same markup inside /guides/install/index.html resolves to /guides/install/images/logo.svg, which often does not exist.
Where this shows up most
- Theme assets referenced with
./or no leading slash - Inline background images in HTML:
style="background-image:url('images/bg.png')" - Generated pages copied into nested folders during export
A useful contrast: URLs inside a stylesheet are resolved from the CSS file’s location, not the page using it. So url('../images/bg.png') inside /assets/theme.css may work everywhere, while the same background path written inline breaks on deeper routes.
If only nested pages fail, treat it as a resolution-context mismatch first. Then switch to correct root-aware paths or emit URLs with the proper base prefix.
When only certain images disappear
Selective breakage usually points to asset discovery, not delivery. The exporter found obvious <img src> files, but missed images introduced through alternate attributes, late rendering, or plugin-generated markup. That pattern matters: if a logo survives while gallery items, sliders, or featured blocks vanish, the crawl likely never saw those URLs.
Match the symptom to the source
- Images load in WordPress but not in the static copy until scrolling: often stored in
data-src,data-lazy,srcset, or<noscript>fallbacks. A simple HTML scraper may only capturesrc. - Single images work but gallery items fail: gallery shortcodes, block JSON, or attachment arrays may render through templates the exporter does not parse completely.
- Only images from custom sections are missing: URLs may live in custom fields, repeater data, or theme options rather than the post body.
- Media inside tabs, sliders, or filtered grids disappears: JavaScript may inject those nodes after load, leaving nothing for a non-rendering crawler to collect.
- Failures follow a specific plugin: that is often why certain WordPress plugins fail on static sites—their output depends on runtime queries, AJAX, or client-side assembly.
What usually fixes it
Use one of three strategies:
- Pre-render pages so lazy and JS-built markup becomes real HTML.
- Whitelist known media directories, attachment endpoints, or custom-field sources.
- Explicitly include gallery assets, ACF image fields, and plugin-generated files in export rules.
If the missing set is predictable, discovery—not hosting—is the real fault line.
When originals load but variants fail
A particularly telling pattern is this: the original uploaded file loads, but its derivatives do not. Full-size JPEGs may appear while thumbnails, cropped versions, srcset candidates, or WebP/AVIF alternatives return 404s. That usually means export succeeded for source media, but the site still expects runtime image processing after deployment.
What this looks like
Typical failures include:
/uploads/photo.jpgworks, but/uploads/photo-300x200.jpgdoes not<picture>fallback loads, but WebP or AVIF URLs fail- only one responsive size exists; the rest of
srcsetis broken - image URLs point to a transform service or optimizer endpoint instead of real files
- query-based transforms such as
?w=800&format=webpstop working on plain static hosting
Static hosts generally serve files; they do not generate new ones on demand. If the site previously relied on a CMS thumbnailer, an edge image CDN, or a framework optimizer route, those URLs remain in HTML but no backend exists to answer them.
How to confirm
Compare a working original against a failing variant. If the broken URL is a resized filename, an optimizer path, or a parameterized transform, the issue is derived-image generation, not missing source media.
What fixes it
- pre-generate all required sizes during build
- disable framework image optimization routes for static export
- rewrite markup to point only to emitted files
- keep an external image transformation service in front of the static site when variants are required
If the broken URL contains a size suffix, optimizer path, or transform parameters, the export is still depending on a live image pipeline.
When production alone breaks
A clean local preview usually means the files and HTML were generated correctly. At that point, the highest-probability failures sit between origin storage, CDN behavior, and edge rewrites.
| Symptom | Likely layer | Fast verification |
|---|---|---|
| Image URL returns 404 only on the public domain | CDN origin path mismatch | Compare the same file on the raw origin and the CDN hostname |
| Request returns 200 but image is broken | SPA fallback or rewrite rule | Check whether the response body is actually index.html with text/html |
| Only WebP/AVIF fail | MIME handling or extension allowlist | Inspect Content-Type, edge rules, and object metadata |
| Images vanish right after deploy, then reappear | stale cache or non-atomic publish | Compare HTML references against the currently uploaded asset set |
| One domain works, another fails | host-based rules, hotlink protection, referrer policy | Repeat the request with each Host value and review WAF rules |
A surprising amount of damage comes from helpful defaults: forced trailing-slash rewrites, lowercase normalization, redirect chains that strip query strings, or object storage rules denying unknown extensions.
The decisive test is the final response chain: status code, Content-Type, cache headers, and body content. If those differ between local and production, another export will not change the outcome.
Pin the failure to one layer before changing anything
-
Inspect the exported output
Confirm whether the missing image file exists in the build artifact. If absent, the fault is usually source access or asset discovery.
-
Compare requested URL with emitted path
Match HTML, CSS, and srcset URLs against actual exported locations. Base paths, subdirectories, and normalization errors surface here.
-
Test original and derived files separately
If originals load but thumbnails, WebP, or transformed URLs fail, derivative generation is the broken layer, not export itself.
-
Bypass CDN and rewrites
Request the asset directly from origin or artifact storage. Success at origin but failure in production points to deployment, caching, or edge rules.
-
Follow this order every time
Files emitted → URLs rewritten correctly → derivatives present → deployment serves bytes. Stop at the first failed check.
Most static-export image failures collapse into four buckets: discovery, path rewriting, derivative generation, or deployment. Classifying the break first prevents wasted debugging in the wrong layer.
The shortest path is mechanical: verify emitted files, verify requested paths, verify derivatives, then verify production delivery. The first mismatch usually names the root cause.