Skip to content

🐛 BUG: Local Images binding ignores EXIF orientation - photos render sideways in local dev #15029

Description

@vdanielb

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

  1. 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();
  },
};
  1. wrangler dev (local): the image is sideways.
  2. 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.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

Status
In Review

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions