gorilla/mux · error · ErrMethodMismatch
method is not allowed
Error message
method is not allowed
What it means
Sentinel error mux.ErrMethodMismatch (mux.go:20). When a request's path matches a registered route but its HTTP method does not match any methodMatcher on that route, Route.Match sets RouteMatch.MatchErr = ErrMethodMismatch (route.go:58) and returns false. Router.Match (mux.go:164) and Router.ServeHTTP (mux.go:220) consult it to emit a 405 instead of a 404. It is a returned sentinel, not a panic.
Source
Thrown at mux.go:20
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mux
import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"path"
"regexp"
)
var (
// ErrMethodMismatch is returned when the method in the request does not match
// the method defined against the route.
ErrMethodMismatch = errors.New("method is not allowed")
// ErrNotFound is returned when no route match is found.
ErrNotFound = errors.New("no matching route was found")
// RegexpCompileFunc aliases regexp.Compile and enables overriding it.
// Do not run this function from `init()` in importable packages.
// Changing this value is not safe for concurrent use.
RegexpCompileFunc = regexp.Compile
// ErrMetadataKeyNotFound is returned when the specified metadata key is not present in the map
ErrMetadataKeyNotFound = errors.New("key not found in metadata")
)
// NewRouter returns a new router instance.
func NewRouter() *Router {
return &Router{namedRoutes: make(map[string]*Route)}
}
// Router registers routes to be matched and dispatches a handler.
//
// It implements the http.Handler interface, so it can be registered to serveView on GitHub (pinned to db9d1d0073)
Solutions
- Add the missing verb to the route's .Methods("GET", "PUT", ...) (and include OPTIONS for CORS preflight).
- Set router.MethodNotAllowedHandler to customize the 405 body.
- Treat errors.Is(match.MatchErr, mux.ErrMethodMismatch) as expected (not an error) in logging/metrics middleware.
Example fix
// before
r.HandleFunc("/users/{id}", h).Methods("GET")
// client does PUT /users/42 -> 405
// after
r.HandleFunc("/users/{id}", h).Methods("GET", "PUT") Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the method is registered before relying on a match
methods, err := route.GetMethods()
if err == nil && !contains(methods, req.Method) {
write405(w, req)
return
} Type guard
// Narrow the match failure to a method mismatch
func isMethodMismatch(m mux.RouteMatch) bool {
return errors.Is(m.MatchErr, mux.ErrMethodMismatch)
} Try / catch
var match mux.RouteMatch
if r.Match(req, &match) {
match.Handler.ServeHTTP(w, req)
return
}
if errors.Is(match.MatchErr, mux.ErrMethodMismatch) {
// 405 path
} Prevention
- Register a MethodNotAllowedHandler so 405s are visible and consistent.
- List every supported verb (including OPTIONS for CORS) on each route.
- Log match.MatchErr in dev to distinguish 404 from 405.
When it happens
Trigger: Client sends PUT /users/42 when only r.HandleFunc("/users/{id}", h).Methods("GET") is registered. The path matcher succeeds but the methodMatcher fails, so matchErr becomes ErrMethodMismatch; if no other route matches it propagates out in RouteMatch.MatchErr.
Common situations: Forgotten verb in .Methods(...); CORS preflight OPTIONS hitting a route that does not list OPTIONS; REST verb typo; load-balancer HEAD/health probes against GET-only routes; reverse proxy rewriting the method.
Related errors
- no matching route was found
- key not found in metadata
- skip this router
- mux: duplicated route variable %q
- mux: number of parameters must be multiple of 2, got %v
AI-assisted analysis of gorilla/mux@db9d1d0073 (2026-08-04).
Data as JSON: /data/errors/bd7345029e296408.json.
Report an issue: GitHub.