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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions