Which Cloudflare product(s) does this pertain to?
Miniflare
What versions are you using?
miniflare 4.20260730.0 (also present on main at time of filing)
What operating system and version are you using?
Windows 11 (reproduces on all platforms)
Describe the Bug
Observed behavior
The local (low-fidelity) Images binding polyfill does not apply EXIF orientation before transforming. Photos taken on phones (commonly stored as landscape pixels + EXIF Orientation: 6) come back sideways from env.IMAGES.input(...).transform(...) in local dev.
In production, the Images binding auto-applies EXIF orientation before transforms, so the same code produces upright images when deployed. This is a local/production fidelity gap that makes phone photos appear rotated 90° only in local dev.
Related: #14795 fixed the fit/gravity/background handling in the same code path (thanks!). Before that fix this bug presented as sideways + black letterbox bars; after it, images are still sideways.
Where it happens
In packages/miniflare/src/plugins/images/fetcher.ts, both local fetchers construct sharp without EXIF auto-orientation:
imagesLocalFetcher: const transformer = sharp(await body.arrayBuffer(), {});
cfImageLocalFetcher: const transformer = sharp(source);
runTransform only applies an explicit transform.rotate value; a parameterless EXIF-based rotation is never applied.
Expected behavior
The local binding should match production and orient images per their EXIF flag before applying user transforms. Since miniflare already depends on sharp 0.35.x, this is a one-line-per-fetcher fix:
sharp(await body.arrayBuffer(), { autoOrient: true })
(autoOrient bakes the EXIF rotation into pixels at decode and clears the orientation flag; an explicit user rotate then composes on top with production-matching semantics.)
Downstream impact
Any framework whose dev server routes image optimization through the local binding shows user photos sideways in dev but correct in production. Concretely: Astro's @astrojs/cloudflare adapter serves /_image through env.IMAGES in astro dev, so any EXIF-rotated photo renders sideways locally — this is how I found the bug.
Please provide a link to a minimal reproduction
See steps below — the repro is a few lines in any Worker with an images binding.
Steps to reproduce
- Create a Worker with an
images binding and this handler:
export default {
async fetch(request, env) {
const src = await fetch("https://github.com/recurser/exif-orientation-examples/raw/master/Portrait_6.jpg");
const result = await env.IMAGES.input(src.body)
.transform({ width: 300 })
.output({ format: "image/jpeg" });
return result.response();
},
};
wrangler dev (local): the image is sideways.
wrangler dev --remote or deploy: the image is upright.
Please provide any relevant error logs
No errors are logged; the transform succeeds but produces incorrectly oriented output.
Which Cloudflare product(s) does this pertain to?
Miniflare
What versions are you using?
miniflare 4.20260730.0 (also present on
mainat time of filing)What operating system and version are you using?
Windows 11 (reproduces on all platforms)
Describe the Bug
Observed behavior
The local (low-fidelity) Images binding polyfill does not apply EXIF orientation before transforming. Photos taken on phones (commonly stored as landscape pixels + EXIF
Orientation: 6) come back sideways fromenv.IMAGES.input(...).transform(...)in local dev.In production, the Images binding auto-applies EXIF orientation before transforms, so the same code produces upright images when deployed. This is a local/production fidelity gap that makes phone photos appear rotated 90° only in local dev.
Related: #14795 fixed the
fit/gravity/backgroundhandling in the same code path (thanks!). Before that fix this bug presented as sideways + black letterbox bars; after it, images are still sideways.Where it happens
In
packages/miniflare/src/plugins/images/fetcher.ts, both local fetchers construct sharp without EXIF auto-orientation:imagesLocalFetcher:const transformer = sharp(await body.arrayBuffer(), {});cfImageLocalFetcher:const transformer = sharp(source);runTransformonly applies an explicittransform.rotatevalue; a parameterless EXIF-based rotation is never applied.Expected behavior
The local binding should match production and orient images per their EXIF flag before applying user transforms. Since miniflare already depends on sharp 0.35.x, this is a one-line-per-fetcher fix:
(
autoOrientbakes the EXIF rotation into pixels at decode and clears the orientation flag; an explicit userrotatethen composes on top with production-matching semantics.)Downstream impact
Any framework whose dev server routes image optimization through the local binding shows user photos sideways in dev but correct in production. Concretely: Astro's
@astrojs/cloudflareadapter serves/_imagethroughenv.IMAGESinastro dev, so any EXIF-rotated photo renders sideways locally — this is how I found the bug.Please provide a link to a minimal reproduction
See steps below — the repro is a few lines in any Worker with an
imagesbinding.Steps to reproduce
imagesbinding and this handler:wrangler dev(local): the image is sideways.wrangler dev --remoteor deploy: the image is upright.Please provide any relevant error logs
No errors are logged; the transform succeeds but produces incorrectly oriented output.