Does the response have a Cf-Resized header? If not, then resizing has not been attempted. Possible causes:
- The feature is not enabled in the Cloudflare Dashboard.
- There is another Worker running on the same request. Resizing is "forgotten" as soon as one Worker calls another. Do not use Workers scoped to the entire domain
/*. - Preview in the Editor in Cloudflare Dashboard does not simulate image resizing. You must deploy the Worker and test from another browser tab instead.
When resizing fails, the response body contains an error message explaining the reason, as well as the Cf-Resized header containing err=code:
- 9401 — The required arguments in
{cf:image{…}}options are missing or are invalid. Try again. Refer to Fetch options for supported arguments. - 9402 — The image was too large or the connection was interrupted. Refer to Supported formats and limitations for more information.
- 9403 — A request loop occurred because the image was already resized or the Worker fetched its own URL. Verify your Worker path and image path on the server do not overlap.
- 9406 & 9419 — The image URL is a non-HTTPS URL or the URL has spaces or unescaped Unicode. Check your URL and try again.
- 9407 — A lookup error occurred with the origin server's domain name. Check your DNS settings and try again.
- 9404 — The image does not exist on the origin server or the URL used to resize the image is wrong. Verify the image exists and check the URL.
- 9408 — The origin server returned an HTTP 4xx status code and may be denying access to the image. Confirm your image settings and try again.
- 9509 — The origin server returned an HTTP 5xx status code. This is most likely a problem with the origin server-side software, not the resizing.
- 9412 — The origin server returned a non-image, for example, an HTML page. This usually happens when an invalid URL is specified or server-side software has printed an error or presented a login page.
- 9413 — The image exceeds the maximum image area of 100 megapixels. Use a smaller image and try again.
- 9420 — The origin server redirected to an invalid URL. Confirm settings at your origin and try again.
- 9421 — The origin server redirected too many times. Confirm settings at your origin and try again.
- 9422 - The transformation request is rejected because the usage limit was reached. If you need to request more than 5,000 unique transformations, upgrade to an Images Paid plan.
- 9432 — The Images Binding is not available using legacy billing. Your account is using the legacy Image Resizing subscription. To bind Images to your Worker, you will need to update your plan to the Images subscription in the dashboard.
- 9504, 9505, & 9510 — The origin server could not be contacted because the origin server may be down or overloaded. Try again later.
- 9519 - The origin server could not be reached for an unexpected reason (e.g. DNS resolution failure). Ensure the origin is reachable via public DNS.
- 9523 — The
/cdn-cgi/image/resizing service could not perform resizing. This may happen when an image has invalid format. Use correctly formatted image and try again. - 9524 — The
/cdn-cgi/image/resizing service could not perform resizing. This may happen when an image URL is intercepted by a Worker. As an alternative you can resize within the Worker. This can also happen when using apages.devURL of a Cloudflare Pages project. In that case, you can use a Custom Domain instead. - 9520 — The image format is not supported. Refer to Supported formats and limitations to learn about supported input and output formats.
- 9522 — The image exceeded the processing limit. This may happen briefly after purging an entire zone or when files with very large dimensions are requested. If the problem persists, contact support.
- 9529 - The image timed out while processing. This may happen when files with very large dimensions are requested or the server is overloaded.
- 9424, 9516, 9517, 9518 — Internal errors. Please contact support if you encounter these errors.
Some conditions do not fail a transformation, but stop Cloudflare from optimizing an image as well as it otherwise would. The image is still returned with a 200 status code, and a Warning response header explains why. A response can include more than one Warning header. Warnings are advisory and never change the status code.
Optimizing an image costs CPU time, and that cost is only worthwhile if the result can be reused from cache. Before transforming a remote image, Cloudflare inspects the cache directives on the source image response. If the optimized image is unlikely to stay in cache for at least an hour, Cloudflare returns:
Warning: cf-images 299 "cache-control is too restrictive"The source image is treated as poorly cacheable when any of the following is true:
- The directives include
privateorno-store. - The directives include
no-cacheormust-revalidate, and the response has neither anETagnor aLast-Modifiedheader. max-ageis less than3600seconds. Ifs-maxageis present, it is used instead ofmax-age.
Cloudflare then optimizes the image with reduced effort.
To restore full-effort optimization, make the source image cacheable for at least an hour:
- Return
Cache-Control: public, max-age=3600or longer from your origin. Images often suit much longer lifetimes, for examplemax-age=604800. - If you cannot change your origin, use a Cache Response Rule to set the
max-agedirective on origin responses before they reach the Cloudflare cache.
After changing the headers, purge the source image URL so the new directives take effect. Refer to Caching and purging.
These are the limits for images that are stored outside of Images:
- Maximum image size is 100 megapixels (for example, 10,000×10,000 pixels large). Maximum file size is 100 megabytes (MB). GIF/WebP animations are limited to 50 megapixels total (sum of sizes of all frames).
- Bring Your Own IP (BYOIP) is not compatible with Images when optimizing remote images (transformations).
- When Polish can't optimize an image the Response Header
Warning: cf-images 299 "original is smaller"is returned.
Image requests to the origin will be anonymized (no cookies, no auth, no custom headers). This is because we have to have one public cache for resized images, and it would be unsafe to share images that are personalized for individual visitors.
However, in cases where customers agree to store such images in public cache, Cloudflare supports resizing images through Workers on authenticated origins.
Changes to image dimensions or other resizing options always take effect immediately — no purging necessary.
Image requests consists of two parts: running Worker code, and image processing. The Worker code is always executed and uncached. Results of image processing are cached for one hour or longer if origin server's Cache-Control header allows. Source image is cached using regular caching rules. Resizing follows redirects internally, so the redirects are cached too.
Because responses from Workers themselves are not cached at the edge, purging of Worker URLs does nothing. Resized image variants are cached together under their source’s URL. When purging, use the (full-size) source image’s URL, rather than URLs of the Worker that requested resizing.
If the origin server sends an Etag HTTP header, the resized images will have an Etag HTTP header that has a format cf-<gibberish>:<etag of the original image>. You can compare the second part with the Etag header of the source image URL to check if the resized image is up to date.
If you use URL rewrite rules to send image requests through /cdn-cgi/image/, rewrite rules are also evaluated on purge requests. This can cause a single-file purge to return a success response without clearing the cached image.
To resolve this, exclude purge requests from the rewrite rule by adding the following to the rule expression:
and (not (http.request.method eq "PURGE"))If you cannot modify your rewrite rules, purge by prefix and purge by cache tag are alternatives.
For related guidance on purging URLs that a Transform Rule modifies, refer to Purge by single file.