# Fixing empty responses from Cloudflare Workers Sites

> A quick fix for empty response bodies on Cloudflare Workers Sites

Author: Simon Hearne (https://simonhearne.com/about/)
Published: 2022-02-22
Canonical: https://simonhearne.com/2022/empty-responses-cloudflare-workers-sites/
Tags: development

---
I'm currently working on a client project using Cloudflare Workers Sites. Mostly development has been a joy, the `wrangler` CLI is easy to use and production deployment happens in seconds.

There was one strange issue reported by the client which left me looking for answers: sometimes the pages wouldn't render, other times no styles were applied. Occasionally images wouldn't render.

These issues were obviously critical, and I managed to reproduce them only on the production deployment but not with `wrangler dev`. The cause of the broken pages was empty responses &mdash; occasionally a response would appear to be successful (`200` etc.) but there was no content in the body. I had some custom code messing with headers in the document handler, but nothing that modified the CSS or image responses.

The biggest clue to the cause of the issue is that it never occurred with a hard reload, only normal navigations or soft reloads.

It turns out that in this Workers Sites deployment a `last-modified` header is added to responses by default (there's no code in [the bundle](https://github.com/cloudflare/worker-sites-template/blob/master/workers-site/index.js) which does this). As described in my [blog post on caching](/2022/caching-header-best-practices/), this header allows the browser to emit a conditional GET request with the `if-modified-since` header. The correct response from the server is a `200` with the full response if the browser's timestamp is earlier than the server's, or a `304` empty response if the browser has the latest version of the asset.

It appears that this Workers Sites deployment does not correctly respond with a `304` &mdash; instead it emits an empty `200` which causes all of the issues we had observed.

![screenshot of developer tools showing a 200 response with an empty body, with last modified response header and if modified since request header](https://simonhearne.com/images/cf_empty_response.png)
*Empty 200 responses when if-modified-since request header set.*

I'm not a fan of `last-modified` as a caching strategy (especially without a `cache-control` directive) so my quick fix was to delete this response header in the event handler function in `index.js`:

```jsx
async function handleEvent(event) {
  const url = new URL(event.request.url)
  let options = {}
  try {
    const page = await getAssetFromKV(event, options)
    const response = new Response(page.body, page)

    response.headers.set('X-XSS-Protection', '1; mode=block')
    response.headers.set('X-Content-Type-Options', 'nosniff')
    response.headers.set('X-Frame-Options', 'DENY')
    response.headers.set('Referrer-Policy', 'unsafe-url')
    response.headers.set('Feature-Policy', 'none')

    // delete the Last-Modified response header
    response.headers.delete('Last-Modified')

    return response
  }
...
```

I still need to implement a correct caching strategy, but at least the site works consistently now!

I've reviewed other Workers Sites properties that I manage and the `last-modified` response header is not set on those. I'm not sure what is different with this property except that it is the most recent new deployment.

