gin-gonic/gin · critical
URL parameters can not be used when serving a static folder
Error message
URL parameters can not be used when serving a static folder
What it means
StaticFS (routergroup.go:205) panics when the relativePath contains ':' or '*', because StaticFS itself registers a /*filepath wildcard under the hood to serve directory contents. A user-supplied ':' or '*' would collide with Gin's own wildcard and break routing, so Gin rejects it at registration time.
Source
Thrown at routergroup.go:205
return group.returnObj()
}
// Static serves files from the given file system root.
// Internally a http.FileServer is used, therefore http.NotFound is used instead
// of the Router's NotFound handler.
// To use the operating system's file system implementation,
// use :
//
// router.Static("/static", "/var/www")
func (group *RouterGroup) Static(relativePath, root string) IRoutes {
return group.StaticFS(relativePath, Dir(root, false))
}
// StaticFS works just like `Static()` but a custom `http.FileSystem` can be used instead.
// Gin by default uses: gin.Dir()
func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) IRoutes {
if strings.Contains(relativePath, ":") || strings.Contains(relativePath, "*") {
panic("URL parameters can not be used when serving a static folder")
}
handler := group.createStaticHandler(relativePath, fs)
urlPattern := path.Join(relativePath, "/*filepath")
// Register GET and HEAD handlers
group.GET(urlPattern, handler)
group.HEAD(urlPattern, handler)
return group.returnObj()
}
func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem) HandlerFunc {
absolutePath := group.calculateAbsolutePath(relativePath)
fileServer := http.StripPrefix(absolutePath, http.FileServer(fs))
return func(c *Context) {
if _, noListing := fs.(*OnlyFilesFS); noListing {
c.Writer.WriteHeader(http.StatusNotFound)
}View on GitHub (pinned to 34dac209ff)
Solutions
- Mount the folder on a plain prefix with no params: router.Static("/static", "./public").
- To serve per-user folders, register a GET handler with c.Param and a custom http.FileServer, or chain groups (router.Group("/user/:id").Static("/files", dir)).
- If you need parametrised static files, write an explicit handler instead of Static/StaticFS.
Example fix
// before
router.Static("/static/:bucket", "./public")
// after
router.Static("/static", "./public")
// or parametrised:
router.GET("/:bucket/*filepath", func(c *gin.Context) {
c.FileFromFS(filepath.Join(c.Param("bucket"), c.Param("filepath")), http.Dir("./public"))
}) Defensive patterns
Strategy: validation
Validate before calling
if strings.ContainsAny(relativePath, ":*") {
log.Fatalf("static folder path %q must not contain URL parameters", relativePath)
}
router.StaticFS(relativePath, fs) Prevention
- Mount Static/StaticFS on plain prefixes (no : or *).
- For per-user folders, write a custom GET handler with c.Param.
- Remember StaticFS already adds /*filepath internally — don't add your own wildcard.
When it happens
Trigger: router.Static("/static/:dir", "./public") or router.StaticFS("/files/*name", fs) — passing a param/wildcard segment to a folder-serving route.
Common situations: Confusing Static (folder) with StaticFile (single file); trying to inject path params into a static directory mount; building the path from user input that happens to contain a colon.
Related errors
- URL parameters can not be used when serving a static file
- http method ${httpMethod} is not valid
- gin mode unknown: ${value} (available mode: debug release te
- key %v does not exist
- the HTML debug render was created without files or glob patt
AI-assisted analysis of gin-gonic/gin@34dac209ff (2026-08-04).
Data as JSON: /data/errors/79582fbd7db83f28.json.
Report an issue: GitHub.