gin-gonic/gin · critical

http method ${httpMethod} is not valid

Error message

http method ${httpMethod} is not valid

What it means

RouterGroup.Handle (routergroup.go:105) panics when the httpMethod argument does not match ^[A-Z]+$ — i.e. it must be non-empty, ASCII, uppercase letters only. This is a startup-time validation because routes are registered at boot; lowercase or non-standard methods are rejected.

Source

Thrown at routergroup.go:105

	absolutePath := group.calculateAbsolutePath(relativePath)
	handlers = group.combineHandlers(handlers)
	group.engine.addRoute(httpMethod, absolutePath, handlers)
	return group.returnObj()
}

// Handle registers a new request handle and middleware with the given path and method.
// The last handler should be the real handler, the other ones should be middleware that can and should be shared among different routes.
// See the example code in GitHub.
//
// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut
// functions can be used.
//
// This function is intended for bulk loading and to allow the usage of less
// frequently used, non-standardized or custom methods (e.g. for internal
// communication with a proxy).
func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers ...HandlerFunc) IRoutes {
	if matched := regEnLetter.MatchString(httpMethod); !matched {
		panic("http method " + httpMethod + " is not valid")
	}
	return group.handle(httpMethod, relativePath, handlers)
}

// POST is a shortcut for router.Handle("POST", path, handlers).
func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodPost, relativePath, handlers)
}

// GET is a shortcut for router.Handle("GET", path, handlers).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodGet, relativePath, handlers)
}

// DELETE is a shortcut for router.Handle("DELETE", path, handlers).
func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) IRoutes {
	return group.handle(http.MethodDelete, relativePath, handlers)
}

View on GitHub (pinned to 34dac209ff)

Solutions

  1. Use the canonical http.Method* constants (http.MethodGet, http.MethodPost, ...) instead of string literals.
  2. Upper-case and validate any method coming from configuration: method = strings.ToUpper(method); check with regexp/ASCII before calling Handle.
  3. For non-standard but valid uppercase methods (e.g. WebDAV COPY, LOCK), pass them in uppercase.

Example fix

// before
router.Handle("get", "/users", h)
// after
router.Handle(http.MethodGet, "/users", h)
Defensive patterns

Strategy: validation

Validate before calling

if !regexp.MustCompile(`^[A-Z]+$`).MatchString(method) {
    log.Fatalf("invalid HTTP method %q for route %s", method, path)
}
router.Handle(method, path, h)

Prevention

When it happens

Trigger: Calling router.Handle("get", "/", h) (lowercase); router.Handle("GET ", ...) (trailing space); router.Handle("PATCH;X", ...) (non-letter); router.Handle("", ...) (empty); using a custom method with a hyphen like "FOO-BAR".

Common situations: Lowercasing the method via strings.ToLower somewhere; passing a method from an untrusted source; copy-paste from RFC examples that use lowercase; using WebDAV methods with mixed case.

Related errors


AI-assisted analysis of gin-gonic/gin@34dac209ff (2026-08-04). Data as JSON: /data/errors/6ee279fed3887021.json. Report an issue: GitHub.