Unexplainable root uri in spring boot prometheus metrics
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When using Spring Boot Actuator with Micrometer and Prometheus, you may see HTTP request metrics with a uri="root" or uri="/" tag that you did not expect. This typically comes from health check probes (Kubernetes liveness/readiness), load balancer health checks, or bots/scanners hitting the root path. Spring Boot's Micrometer integration tags every HTTP request with a uri label, and requests to unmapped paths get tagged with uri="/**" or the actual path. Understanding where these requests originate and how to filter or relabel them is key to keeping your Prometheus metrics clean.
The Symptom
The uri="/" metric has a high count but you have no controller mapped to /.
Common Sources of Root URI Requests
- Kubernetes probes: Default liveness/readiness probes hit
/if not configured to a specific path - Load balancer health checks: AWS ALB, GCP LB, or Nginx default health checks hit
/ - Bots and scanners: Web crawlers and vulnerability scanners probe the root path
- Spring Boot welcome page: If you have an
index.htmlinstatic/, Spring Boot serves it at/ - Actuator redirects: Misconfigured actuator base path can cause redirects through
/
Identifying the Source
Fix 1: Configure Kubernetes Probes Properly
Fix 2: Filter Out Root URI from Metrics
Use a MeterFilter to ignore or rename the root URI in metrics.
Or rename the URI tag to group health check traffic:
Fix 3: Customize URI Tag via WebMvcTagsContributor
Fix 4: Prometheus Relabeling
Filter out the root URI at the Prometheus scrape level:
Common Pitfalls
- Kubernetes default probes hitting root path: If you do not configure
livenessProbe.httpGet.path, some Kubernetes setups default to/. Every probe interval generates a metric entry, inflatinguri="/"counts. Always set explicit probe paths pointing to/actuator/health. - High cardinality from unmapped URIs: Requests to paths like
/wp-admin,/phpmyadmin, or other scanner targets create uniqueuritag values, causing cardinality explosion in Prometheus. Spring Boot 2.6+ replaces unmapped paths withuri="/**", but custom error handling may override this. - Filtering metrics too aggressively: Denying all
uri="/"metrics also hides legitimate traffic if you have a controller mapped to/. Use the logging filter first to identify the source before filtering metrics. - Not setting
management.server.port: Running actuator endpoints on the same port as the application means health check traffic shows up in application request metrics. Setmanagement.server.port: 9090to separate actuator traffic onto a different port, keeping application metrics clean. - Prometheus relabeling dropping all root metrics: The
metric_relabel_configsdrop rule applies to all metrics withuri="/", including any you intentionally want to monitor. Use more specific rules that also matchstatusormethodto target only health check traffic.
Summary
uri="/"in Prometheus metrics usually comes from Kubernetes probes, load balancer health checks, or scanners- Configure probes to hit
/actuator/health/livenessand/actuator/health/readinessinstead of/ - Use
MeterFilter.deny()to filter unwanted root URI metrics at the application level - Use Prometheus
metric_relabel_configsto drop or rename metrics at the scrape level - Separate actuator and application traffic with
management.server.portto keep metrics clean

