#6671·shenyu

[BUG] — Prometheus `counter` labeled by raw request `path` → high-cardinality children map grows unbounded

Author: Aias00Created Aug 3, 2026Updated Sep 9, 2026
Labelstype: performancemetrics: prometheuspriority: high
  • 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<List<String>, 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.