Skip to content

[Bug]: Published pages return 404 to HEAD requests but 200 to GET #306

Description

@ngocht

Summary

Published pages answer HEAD with 404 {"error":"Not found"} while answering GET with 200 and the page. HEAD is supposed to be identical to GET minus the body (RFC 9110 §9.3.2), so any client that probes with HEAD concludes the site is missing.

This matters in practice because HEAD is the conventional method for uptime monitoring and link checking. A monitor pointed at the public site reports it permanently down even though the site is fine, and link checkers report every internal link as broken.

Steps to reproduce

On any install with a published page:

$ curl -s -o /dev/null -w '%{http_code}\n' -X GET  https://example.com/
200

$ curl -s -o /dev/null -w '%{http_code}\n' -I https://example.com/
404

Reproduced against the container directly (no reverse proxy involved), so it is not proxy-related:

$ for P in /health /admin / /kontakt; do
    printf "%-12s GET=%s HEAD=%s\n" "$P" \
      "$(curl -s -o /dev/null -w '%{http_code}' -X GET  http://127.0.0.1:3001$P)" \
      "$(curl -s -o /dev/null -w '%{http_code}' -I     http://127.0.0.1:3001$P)"
  done
/health      GET=200 HEAD=200
/admin       GET=200 HEAD=200
/            GET=200 HEAD=404
/kontakt     GET=200 HEAD=404

/health and /admin are fine; only the published-site routes are affected.

Expected behavior

HEAD on a published page returns the same status code and headers as GET, with no body.

Actual behavior

HEAD returns 404 with a JSON body {"error":"Not found"}.

Minor, possibly separate

/admin/api/cms/setup/status answers HEAD with 405 rather than 404. That is more defensible for a JSON API endpoint, but it is a third behaviour for the same method across the app, so mentioning it in case the fix wants to be uniform.

Version or commit

0.0.14 (ghcr.io/corebunch/instatic:0.0.14)

Deployment mode

Docker, Postgres, behind nginx — though as shown above it reproduces against the container directly.

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