Configuring Cloudflare Image Resizing URL parameters
The /cdn-cgi/image/<options>/<source> URL is deceptively simple: a comma-separated option list, then the path to your master. But each option interacts with the others, and a wrong fit or a missing format=auto quietly ships the wrong bytes. This guide — part of Cloudflare Image Resizing and Polish within CDN & Edge Media Delivery — walks every option in the string, gives one fully annotated worked example, and shows the exact curl that proves the edge did what you asked.
Prerequisite checklist
Anatomy of the URL
The URL has three fixed segments, and getting their boundaries right matters more than any single option. The prefix triggers interception, the middle segment carries the options, and the tail names the master. The options are part of the path, never a query string.
The option string, parameter by parameter
Options are a comma-separated list with key=value pairs, placed between /cdn-cgi/image/ and the source path. Order does not matter; unknown keys are ignored.
Sizing: width, height, dpr, fit
width(w) — target width in device pixels. This is the primary lever; it is what actually shrinks payloads. Bound it to your breakpoint set.height(h) — target height. With only one of width/height set, the other is derived from the aspect ratio.dpr— device-pixel-ratio multiplier applied on top ofwidth.width=320,dpr=2produces a 640-pixel image intended to paint into a 320 CSS-pixel slot on a 2× display.fit— how the image is fitted to thewidth×heightbox:scale-down— fit within the box, never enlarge. Preserves aspect ratio. Safest default.contain— fit within the box, may enlarge. Preserves aspect ratio.cover— fill the box, cropping overflow. Preserves aspect ratio; pair withgravity.crop— fill and hard-crop to the exact box dimensions.pad— fit within the box and pad the remainder withbackground.
Format and quality: format, quality
format=auto— negotiate AVIF/WebP/JPEG from the requestAcceptheader. This is what makes one URL serve the right codec to every client. Omit it and you get the source format for everyone.quality(q) — perceptual quality 1–100. Around 75 is a strong photographic default; drop to 55–65 for thumbnails, raise to 85+ for detailed hero art.
Cropping and focus: gravity, background
gravity— focal point forcover/crop. Acceptsauto(saliency detection), a side (left,right,top,bottom), or normalized coordinates like0.5x0.2(horizontal×vertical, 0–1).background— fill colour forfit=pador for flattening transparency when producing a format without an alpha channel. Accepts CSS colours or%23RRGGBB(URL-encoded hex).
Detail and robustness: sharpen, metadata, onerror, anim
sharpen— 0–10 unsharp-mask strength. Downscaling softens edges;sharpen=1recovers crispness on photos, higher values over-sharpen.metadata—none(default, strips EXIF),copyright(keeps only copyright), orkeep(retains all EXIF, larger files).onerror— what to do if the master cannot be fetched or resized.redirectserves the original source instead of an error, so a broken transform degrades to the unoptimized image rather than a broken icon.anim—truepreserves animation frames (animated WebP/GIF);anim=falsecollapses an animation to its first frame, useful for generating a static poster.
Worked example — one fully annotated URL
The following URL derives a 640-pixel-wide, cover-cropped, negotiated variant from a portrait master, keeping the subject’s face in frame and degrading gracefully if the master is missing:
<!--
Break the option string down comma by comma:
width=640 target 640 device pixels wide (a real breakpoint)
height=800 target height; with width this defines a 4:5 box
fit=cover fill the whole 640x800 box, cropping overflow
gravity=0.5x0.3 keep the crop centred horizontally, biased UP toward
the face (0.3 vertical) rather than the geometric centre
quality=75 perceptual quality target for photographic content
format=auto negotiate AVIF/WebP/JPEG from the request Accept header
sharpen=1 restore edge crispness lost when downscaling the master
metadata=none strip EXIF to shave bytes and remove location data
onerror=redirect if the master 404s or fails, serve the original source
instead of a broken image
The trailing /media/portraits/anaïs-master.jpg is the ORIGIN path of the
master. Note the source is URL-relative to the same zone.
-->
<img
src="/cdn-cgi/image/width=640,height=800,fit=cover,gravity=0.5x0.3,quality=75,format=auto,sharpen=1,metadata=none,onerror=redirect/media/portraits/anais-master.jpg"
width="640" height="800"
alt="Studio portrait, cropped to the subject's face"
loading="lazy" decoding="async">
Warning: the option string is before the source path, not a query string. A frequent mistake is writing /media/img.jpg?width=640 — Cloudflare Image Resizing ignores query-string options entirely and serves the untouched source. The options must sit in the path segment right after /cdn-cgi/image/.
Warning: if you pass background as a hex colour, URL-encode the # as %23 (for example background=%23ffffff). A literal # starts the URL fragment and the parameter is silently dropped.
Verification
Confirm the negotiated format and that Resizing ran
# Simulate a Chrome request (advertises AVIF + WebP). A correct transform
# returns content-type: image/avif and a cf-resized header. The cf-resized
# header appears ONLY when Image Resizing processed the request — its
# absence means the option string was ignored (feature off, or query-string
# mistake) and the source was served untouched.
curl -sI -H 'Accept: image/avif,image/webp,*/*;q=0.8' \
'https://yoursite.com/cdn-cgi/image/width=640,height=800,fit=cover,quality=75,format=auto/media/portraits/anais-master.jpg' \
| grep -iE 'content-type|cf-resized|cf-cache-status'
# Expected:
# content-type: image/avif
# cf-resized: internal=ok/…
# cf-cache-status: HIT
Confirm the fallback tier for Safari 14
# Safari 14 advertises WebP but not AVIF. The same URL must return WebP here,
# proving format=auto negotiated correctly rather than forcing one codec.
curl -sI -H 'Accept: image/webp,image/*,*/*;q=0.8' \
'https://yoursite.com/cdn-cgi/image/width=640,height=800,fit=cover,quality=75,format=auto/media/portraits/anais-master.jpg' \
| grep -i 'content-type'
# Expected: content-type: image/webp
Confirm the actual delivered dimensions
# Download the transformed bytes and read the intrinsic size, proving the
# resize happened (not just a re-encode at native resolution). identify ships
# with ImageMagick; use `file` if you only need the format.
curl -s -H 'Accept: image/avif' \
'https://yoursite.com/cdn-cgi/image/width=640,height=800,fit=cover,format=auto/media/portraits/anais-master.jpg' \
-o /tmp/variant.avif
identify -format '%wx%h %m\n' /tmp/variant.avif
# Expected: 640x800 AVIF
Common mistakes
1. Options placed as a query string
Symptom: the full-size source is served; cf-resized is absent.
Cause: options written as ?width=640 instead of in the path.
Fix: move them into the path: /cdn-cgi/image/width=640,format=auto/media/img.jpg.
2. format=auto omitted
Symptom: Chrome receives JPEG even though AVIF was expected.
Cause: without format=auto, Resizing keeps the source format.
Fix: always include format=auto unless you deliberately want a fixed codec.
3. Continuous widths from client JavaScript
Symptom: cache hit rate near zero; transform bill climbs.
Cause: passing window.innerWidth (751, 752, 753…) mints a new variant per pixel.
Fix: snap to a fixed breakpoint set before building the URL — the clamp pattern shown in Cloudflare Image Resizing and Polish.
4. fit=cover with no gravity on portraits
Symptom: faces cropped off the top of tall images.
Cause: cover defaults to a centre crop.
Fix: set gravity to auto or explicit coordinates biased toward the subject.
5. Upscaling with fit=contain
Symptom: small masters look soft and blocky at large width.
Cause: contain enlarges past the master’s intrinsic size.
Fix: use fit=scale-down so the edge never upscales beyond the source resolution.
Related
- Cloudflare Image Resizing and Polish — the parent guide covering Workers
cf.image, Polish, and when to use each engine - Cloudflare Polish vs Image Resizing: tradeoffs — deciding between the option string here and zero-config Polish
- CDN & Edge Media Delivery — cache-key design and Accept negotiation behind these parameters
- Cache-Control Headers for Image and Video Assets — immutable master URLs so long TTLs on derived variants stay safe