[BUG] — Prometheus `counter` labeled by raw request `path` → high-cardinality children map grows unbounded
- Dominant language
- Java
- Stars
- 8.8k
- Forks
- 3.1k
- Avg merge
- 7d 1h
- Merged PRs (30d)
- 85
Description
- severity: High
- files: `shenyu-plugin/shenyu-plugin-metrics/src/main/java/org/apache/shenyu/plugin/metrics/MetricsPlugin.java:49` (`counterIncrement(LabelNames.REQUEST_TYPE_TOTAL, new String[]{exchange.getRequest().getURI().getRawPath(), shenyuContext.getRpcType()})`); label registration `MetricsReporter.java:43` (names `{"path","type"}`); impl `PrometheusMetricsRegister.java:64` (`counter.labels(labelValues)` lazily creates a `Counter.Child` per distinct vector)
- description: `rawPath` is the literal request path. Parameterized paths (`/api/user/123`, `/api/order/456`) produce a distinct label vector per distinct path, so the Prometheus client's internal `ConcurrentHashMap, Child>` grows monotonically over the gateway's lifetime with no eviction. The outer `COUNTER_MAP`/`GAUGE_MAP`/`HISTOGRAM_MAP` are bounded by metric name, but the per-child series map inside each Counter is not. Textbook high-cardinality-label memory leak.
- impact: Unbounded heap growth proportional to distinct request paths; OOM on a public-facing gateway with arbitrary path parameters; also inflates `/metrics` scrape size.
- suggested_fix: Do not label by raw `path`; label by a bounded dimension (rpcType, selector id, or a low-cardinality route tag). If per-path granularity is needed, use a fixed allow-list of path templates.
- confidence: High
---
_Identified during the 2026-08-02 deep re-scan; full list in [`docs/scan2-2026-08-02/00-consolidated-critical-high.md`](docs/scan2-2026-08-02/00-consolidated-critical-high.md)._
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.