gorilla/mux · error · ErrMetadataKeyNotFound

key not found in metadata

Error message

key not found in metadata

What it means

Sentinel error mux.ErrMetadataKeyNotFound (mux.go:28). Returned by Route.GetMetadataValue (route.go:155-162) when the requested key is absent from the route's metadata map (populated via Route.Metadata). Lets callers distinguish 'absent key' from 'present with zero value'. The non-erroring alternative is GetMetadataValueOr (route.go:165).

Source

Thrown at mux.go:28

	"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 serve
// requests:
//
//	var router = mux.NewRouter()
//
//	func main() {
//	    http.Handle("/", router)
//	}
//

View on GitHub (pinned to db9d1d0073)

Solutions

  1. Use route.GetMetadataValueOr(key, default) when a default exists.
  2. Guard with route.MetadataContains(key) first, or read GetMetadata() and use the comma-ok form.
  3. Define metadata keys as typed constants so the key type/value stays consistent.

Example fix

// before
v, err := route.GetMetadataValue("rate")
// err == mux.ErrMetadataKeyNotFound on untagged routes

// after
v := route.GetMetadataValueOr("rate", defaultRate)
Defensive patterns

Strategy: fallback

Validate before calling

if !route.MetadataContains(key) {
    return defaultValue
}

Type guard

func hasMetadata(r *mux.Route, key any) bool { return r != nil && r.MetadataContains(key) }

Try / catch

v, err := route.GetMetadataValue(key)
if err != nil {
    if errors.Is(err, mux.ErrMetadataKeyNotFound) {
        v = fallback
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: Calling route.GetMetadataValue("rateLimit") on a route that never had .Metadata("rateLimit", v) called, or whose metadata map is nil because no metadata was ever set.

Common situations: Middleware reading optional metadata (rate limit, auth role, cache TTL) applied to only some routes; key type drift (string vs custom typed key); refactor renaming a metadata key in the builder but not the middleware.

Related errors


AI-assisted analysis of gorilla/mux@db9d1d0073 (2026-08-04). Data as JSON: /data/errors/ea53ab712cfda496.json. Report an issue: GitHub.