Image Optimization issue with extension-less paths

I’m working on a web app that can serve up images through dynamic paths unrelated to the image type itself. The examples provided in the documentation all rely on detecting the extension of the path to see if it’s an image type (png, gif, jpg). In my case, I want to check the content-type response from the backend, and then enable IO on that request.

For example, given the following path directly to an image, we can see that it is returning an image content-type and is being processed by IO.

curl -I
HTTP/1.1 200 OK
Content-Length: 3973506
Cache-Control: no-cache, must-revalidate
Content-Type: image/jpeg
Fastly-Io-Info: ifsz=4276205 idim=3974x5961 ifmt=jpeg ofsz=3973506 odim=3974x5961 ofmt=jpeg
Fastly-Restarts: 1
Fastly-Stats: io=1

The same image, but being returned in a dynamic path with the same content-type and content-length, I get a “response is pass” error.

curl -I
HTTP/1.1 200 OK
Content-Length: 4276205
Accept-Ranges: bytes
Age: 279
Cache-Control: max-age=600
Content-Type: image/jpeg
Fastly-Io-Error: response is pass
Fastly-Stats: io=1

This is (mostly) the only logic I’m applying.

# vcl_deliver
# Check the response content-type and that header wasn't already set  or request restarted.
if (resp.http.Content-Type ~ "(?i)(gif|png|jpe?g|webp)" && !req.http.X-Fastly-Imageopto-Api && req.restarts == 0) {
  # Enable IO
  set req.http.X-Fastly-Imageopto-Api = "fastly; qp=*";

  # Restart the request to trigger Fastly IO processing

My main question here is, does IO only work on paths that include an image extension?

Hi @kyletaylored

Just wanted to let you know I’ve enquired internally, and hope to hear back shortly.


1 Like

Hi @kyletaylored

So I spoke to the IO team who believe what you’re trying to do should work.

They created a Fastly Fiddle to demonstrate:

They noticed in the response to your second request:

Fastly-Io-Error: response is pass

This implies that the response from origin is not cacheable (or the VCL is returning pass somewhere else) which is probably a separate issue

I think it would be worth you reaching out to so the Customer Services team can help debug your actual service.


Amazing, that’s exactly what I was looking to confirm! I can confirm the origin is returning a cacheable response, but I’ll see if I can track down anything else within the VCL that would be returning a pass.

Thanks for your help @Integralist! I was able to find where a pass was being returned and can now see dynamic image paths being processed by IO.


Great news! Thanks for the update :+1:t2:

Actually, coming back to this. Do you think this snippet could be added to the Image Optimizer Reference document? Only because initially, the current doc makes it appear that you are limited to the data in the initial request (like the file extension), but in reality you can also check the backend response for the content-type being image/*, which could be more accurate.

Once I realized this was a possibility, what I was trying to do became much simpler! Just a suggestion.


Great idea @kyletaylored I’ll get a ticket to update the docs :+1:

Thanks again for the feeback!

Example code posted to (with signpost from IO reference. Thanks for the suggestion :slight_smile:

1 Like