Azure / Azure/azure-functions-host
HTTP GET triggers should auto-handle HEAD requests (or return clearer error)
- Dominant language
- C#
- Stars
- 2k
- Forks
- 482
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 37
Description
## Summary
When an Azure Function has an HTTP trigger configured for GET only, HEAD requests return a generic 404 from the routing layer rather than being auto-handled or returning a clear "method not allowed" error. This causes significant debugging confusion.
## Problem
A function defined as:
```csharp
[Function("RedirectUrl")]
public async Task RedirectUrl(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "r/{shortCode}")] HttpRequest req,
string shortCode)
```
**Behavior:**
- `GET /api/r/abc123` → **302 Found** ✅ (works)
- `HEAD /api/r/abc123` → **404 Not Found** ❌ (confusing)
The 404 comes from the routing layer before the function is invoked, with no indication that HEAD is unsupported.
## Why This Matters
1. **Common testing pattern**: Developers frequently use `curl -I` (HEAD) to test redirects and check response headers without downloading the body
2. **Debugging time waste**: I spent ~20 minutes debugging why redirects "weren't working" before realizing HEAD vs GET was the issue
3. **HTTP spec expectation**: RFC 7231 states "The HEAD method is identical to GET except that the server MUST NOT send a message body" - many developers expect GET endpoints to auto-handle HEAD
## Suggested Fix (in priority order)
### Option A: Auto-handle HEAD for GET triggers (Preferred)
When a function accepts GET, automatically handle HEAD by:
1. Invoking the function with the HEAD request
2. Returning headers only (strip body)
This matches behavior of most web frameworks (ASP.NET Core, Express, Flask, etc.)
### Option B: Return 405 Method Not Allowed
If HEAD is not supported, return:
```
HTTP/1.1 405 Method Not Allowed
Allow: GET, POST
```
This clearly indicates the method isn't supported and which methods are.
### Option C: Better documentation
At minimum, document that HEAD requests require explicit `"head"` in the trigger:
```csharp
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "head", Route = "...")]
```
## Environment
- Azure Functions Flex Consumption
- .NET 10 isolated worker (net10.0)
- Functions Runtime: 4.1046.x
## Reproduction
1. Create function with `[HttpTrigger(..., "get", ...)]`
2. Deploy to Azure
3. `curl -I https://.azurewebsites.net/api/` → 404
4. `curl https://.azurewebsites.net/api/` → 200/302 (works)
The inconsistency between HEAD and GET is unexpected and causes debugging confusion.
Contributor guide
Research direction
The issue names no repository files or tests. Start by reproducing the HttpTrigger GET-only case with curl, comparing GET and HEAD and confirming that the 404 occurs in the routing layer before invocation. Clarify which proposed outcome is accepted—automatic HEAD handling, a 405 response, or documentation—then add coverage or documentation matching that decision.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, csharp
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100