Skip to content

HEAD requests return 404 for onGet endpoints #8232

@chindris-mihai-alexandru

Description

Which component is affected?

Qwik City (Endpoints)

Describe the bug

Routes with onGet handlers return HTTP 404 for HEAD requests while correctly returning 200 for GET requests. According to HTTP/1.1 spec (RFC 7231), servers SHOULD respond to HEAD requests the same as GET, just without the message body.

Reproduction

  1. Create an endpoint with an onGet handler:
// src/routes/rss.xml/index.ts
import type { RequestHandler } from '@builder.io/qwik-city';

export const onGet: RequestHandler = async ({ send }) => {
  const xml = '<?xml version="1.0"?><rss version="2.0"><channel><title>Test</title></channel></rss>';
  send(new Response(xml, {
    status: 200,
    headers: { 'Content-Type': 'application/rss+xml' },
  }));
};
  1. Deploy to any adapter (tested on Cloudflare Pages)

  2. Test with HEAD vs GET:

# GET request - works fine
curl -s -o /dev/null -w "%{http_code}" https://example.com/rss.xml
# Returns: 200

# HEAD request - returns 404
curl -sI https://example.com/rss.xml | head -1
# Returns: HTTP/2 404

Expected behavior

HEAD requests should return the same status code and headers as GET requests (just without the body). Many frameworks handle this automatically by calling the GET handler and stripping the response body.

Example from Marko framework:

export function head(context) {
  return stripResponseBody(get(context));
}

Actual behavior

HEAD requests to onGet endpoints return 404 because there's no onHead handler defined and Qwik City doesn't auto-generate one from onGet.

Impact

  • Monitoring tools using HEAD requests report false 404 errors
  • SEO validators that use HEAD to check URLs report broken links
  • curl -I (commonly used for debugging) shows 404, confusing developers
  • Breaks HTTP spec compliance

Possible solutions

  1. Auto-generate HEAD handlers from onGet (recommended) - call GET handler, strip body
  2. Add onHead to RequestHandler - allow explicit HEAD handling
  3. Document workaround - use onRequest to handle both methods

System Info

Qwik: 1.12.1
Qwik City: 1.12.1
Node: 22.x
Deployment: Cloudflare Pages (also reproduced locally with wrangler)

Additional context

This was discovered when monitoring an RSS feed endpoint. The site has /rss.xml and /sitemap.xml routes that work perfectly with GET but return 404 for HEAD. Real-world browsers and feed readers use GET, so functionality isn't broken, but it causes confusion during debugging and breaks monitoring.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions