gin-contrib / gin-contrib/timeout
Unmatched routes respond `200 OK` with empty body when middleware is registered globally via Use()
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 237
- Forks
- 42
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 2
Description
When the timeout middleware is registered globally with engine.Use(...), any request that does not match a registered route is answered with 200 OK and an empty body instead of gin's default 404 page not found.
Gin's own access logger still reports 404, so the internal status and the status actually sent on the wire disagree, which makes this very confusing to debug behind a reverse proxy (our ingress logged 200 while the app logged 404).
Registering the middleware per-route (as in _example/example01) does not trigger the bug, because route-level handlers never run for unmatched routes. The examples therefore never exercise this path.
How to reproduce
package main
import (
"net/http"
"time"
"github.com/gin-contrib/timeout"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.New()
r.Use(gin.Logger(), timeout.New(timeout.WithTimeout(30*time.Second)))
r.GET("/hello", func(c *gin.Context) {
c.String(http.StatusOK, "world")
})
_ = http.ListenAndServe(":8080", r)
}
$ curl -si http://127.0.0.1:8080/no/such/route
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 0
Server log for the same request (note the 404):
[GIN] 2026/07/30 - 17:14:57 | 404 | 57.607µs | 127.0.0.1 | GET "/no/such/route"
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with gin.New(), a global timeout.New middleware, the /hello route, and a request to /no/such/route. Start by tracing how the globally registered middleware interacts with Gin's unmatched-route handling and compare the access-log status with the response sent by curl. Done means an unmatched route returns Gin's default 404 page not found response on the wire while routed requests and timeout behavior remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100