Skip to content

CORS headers missing on Fastify-level error responses (FST_ERR_BAD_URL et al) #376

Description

@melvincarvalho

Surfaced during PR #374 review.

When Fastify itself rejects a request before any handler runs (most commonly `FST_ERR_BAD_URL` for malformed percent-encoding like `%g1`, truncated `%E0%`, or invalid UTF-8 sequences), the 400 response carries no `Access-Control-Allow-*` headers. Browser clients then surface the response as a generic CORS / network error instead of the actual status code, which is confusing for debugging and undermines the per-handler CORS work in #371 / #374.

Reproduction

```bash
curl -i -H 'Origin: https://example.com'
'https://melvin.me/melvin/public/git/test-repo.git/info/refs%g1?service=git-upload-pack'
```

```
HTTP/2 400
content-type: application/json
content-length: 155

(no access-control-* headers)

{"error":"Bad Request","code":"FST_ERR_BAD_URL", ...}
```

Scope

This isn't git-specific. The same shape applies to any route — Fastify's URL parser short-circuits before the handler-layer CORS hooks ever run. Possible fixes:

  1. Global `onError` or `onSend` Fastify hook that decorates 4xx/5xx with the standard CORS headers when the request had an `Origin` header.
  2. Use `@fastify/cors` plugin (would replace the per-handler CORS blocks across the codebase — bigger refactor but more consistent long-term).
  3. Custom `schemaErrorFormatter` / `errorHandler` that injects CORS headers on the rejected response.

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions