Skip to content

Duplicate HTTP methods in 405 Allow header #996

Closed

Description

@alexedwards

It seems like when routes are registered which 'overlap' due to their wildcards, their methods are repeated in the Allow header in 405 responses.

Minimal runnable example: https://go.dev/play/p/wm5Roz8MSRJ

package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"

	"github.com/go-chi/chi/v5"
)

func main() {
	r := chi.NewRouter()

	r.Post("/article/1-2-3", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)

	})

	r.Post("/article/{a}", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)

	})

	r.Post("/article/{b}-{c}", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
	})

	r.Post("/article/{b}-{c}-{d}", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
	})

	server := httptest.NewServer(r)
	defer server.Close()

	// Send a request with an unsupported method
	res, err := http.Get(server.URL + "/article/1-2-3")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Status:", res.Status)
	fmt.Println("Header:", res.Header)
}

Outputs:

Status: 405 Method Not Allowed
Header: map[Allow:[POST POST POST POST] Content-Length:[0] Date:[Tue, 10 Nov 2009 23:00:00 GMT]]

The POST value in the Allow header is duplicated four times, which seems strange, and I think ideally it would only appear once.

Activity

  1. priyanshu4999 commented on May 15, 2025

    @priyanshu4999

    Hi @alexedwards,

    I have gone through the issue about duplicate HTTP methods appearing multiple times in the Allow header for 405 responses (#996).

    I’ve implemented a fix where the Allow header values are deduplicated by using a map before adding them to the response headers. This prevents repeated HTTP methods from showing up multiple times.

    I also added tests covering this case to ensure the fix works and avoids regressions.

    If you’re open to it, I can submit a pull request with the changes.

    Thanks!

  2. priyanshu4999 commented on May 15, 2025

    @priyanshu4999

    While writing the response in methodNotAllowedHandler, the code reads all allowed methods registered for overlapping routes. By tracking and avoiding duplicate methods when adding to the Allow header, we resolve the issue of repeated HTTP methods.

    Personally, I think the repeated methods in the Allow header aren’t a functional problem beyond making the header unnecessarily verbose. The real concern is that it exposes all registered method types and their counts, which could be a minor information leak or just clutter.

  3. added 2 commits that reference this issue on Dec 19, 2025
    9001d00
    d95a851
  4. added 3 commits that reference this issue on Feb 10, 2026
    44ecca2
    9904e09
    843c7c2
  5. added a commit that references this issue on Jul 10, 2026
    14cb881
  6. VojtechVitek commented on Aug 20, 2026

    @VojtechVitek
    Contributor

    Thanks everyone. I confirmed the issue and reviewed these competing PRs:

    PR Age Approach
    #1029 Oct 2025 Dedupe at the source in tree.go (slices.Contains before append)
    #1040, #1096, #1124 Dec 2025 – Jul 2026 Near-identical: seen-map inside methodNotAllowedHandler
    #1047 Feb 2026 slices.Sort + Compact in the handler
    #1112 Jun 2026 Refactor methodsAllowed to a bitmask

    Let's go with #1029, which looks like the cleanest zero-allocation fix.

    Closing the other PRs as duplicates — thanks for the contributions, the approaches were all reasonable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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