geektutu/7days-golang · error

HTTPPool serving unexpected path: " + r.URL.Path

Error message

HTTPPool serving unexpected path: " + r.URL.Path

What it means

HTTPPool.ServeHTTP panics when the request path does not start with the pool's basePath (default '/_geecache/'). The handler only serves the cache's internal HTTP API; any other path reaching it means the HTTP routing was misconfigured. This fail-fast panic indicates the server was mounted at the wrong location or a client/proxy is sending wrong paths.

Source

Thrown at gee-cache/day7-proto-buf/geecache/http.go:48

}

// NewHTTPPool initializes an HTTP pool of peers.
func NewHTTPPool(self string) *HTTPPool {
	return &HTTPPool{
		self:     self,
		basePath: defaultBasePath,
	}
}

// Log info with server name
func (p *HTTPPool) Log(format string, v ...interface{}) {
	log.Printf("[Server %s] %s", p.self, fmt.Sprintf(format, v...))
}

// ServeHTTP handle all http requests
func (p *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if !strings.HasPrefix(r.URL.Path, p.basePath) {
		panic("HTTPPool serving unexpected path: " + r.URL.Path)
	}
	p.Log("%s %s", r.Method, r.URL.Path)
	// /<basepath>/<groupname>/<key> required
	parts := strings.SplitN(r.URL.Path[len(p.basePath):], "/", 2)
	if len(parts) != 2 {
		http.Error(w, "bad request", http.StatusBadRequest)
		return
	}

	groupName := parts[0]
	key := parts[1]

	group := GetGroup(groupName)
	if group == nil {
		http.Error(w, "no such group: "+groupName, http.StatusNotFound)
		return
	}

View on GitHub (pinned to cf36443821)

Solutions

  1. Register the HTTPPool handler with http.Handle(pool.BasePath, pool) so only matching paths reach it
  2. If you must mount at a broader path, set p.basePath to the prefix the pool actually serves (Set/construct with matching basePath)
  3. Check upstream proxies/load balancers to ensure they only route cache-prefixed paths to this handler
  4. Wrap ServeHTTP in a recover middleware only for production hardening; fix routing rather than swallowing the panic

Example fix

// before
http.Handle("/", httpPool) // any path reaching ServeHTTP can panic
// after
http.Handle(httpPool.BasePath, httpPool)
Defensive patterns

Strategy: validation

Validate before calling

mux.HandleFunc("/_geecache/", pool.ServeHTTP) // only route basePath-prefixed paths
// or before forwarding:
if !strings.HasPrefix(req.URL.Path, pool.BasePath) {
    http.NotFound(w, r)
    return
}

Try / catch

func safeServe(pool *geecache.HTTPPool) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        defer func() { if recover() != nil { http.Error(w, "bad path", http.StatusNotFound) } }()
        pool.ServeHTTP(w, r)
    }
}

Prevention

When it happens

Trigger: Registering the HTTPPool handler at '/' (or a prefix different from p.basePath) and receiving requests outside basePath; a load balancer forwarding non-cache paths to the cache server; a client constructed with a mismatched base URL prefix.

Common situations: Mounting httpPool on http.HandleFunc("/") while basePath is '/_geecache/'; version upgrades where the default basePath changed; external health checks hitting '/' on the cache port.

Related errors


AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03). Data as JSON: /api/errors/bab06997594cc20a. Report an issue: GitHub.