Introduction
A single malformed HTTP request can terminate any Node.js process running the OpenTelemetry JavaScript Prometheus exporter, taking down not just the metrics endpoint but the entire application. With OpenTelemetry having just graduated from the CNCF on May 21, 2026, as the second most active project after Kubernetes (over 15,000 contributors from 1,800+ organizations), the blast radius of CVE-2026-44902 extends across a significant portion of the cloud native ecosystem.
The vulnerability is a textbook missing error handler: the Prometheus exporter's HTTP server parses incoming request URLs using JavaScript's URL constructor without a try...catch block. When a request arrives with an invalid URI, the resulting TypeError propagates as an uncaught exception and kills the process. The CVSS 3.1 score of 7.5 (HIGH) reflects the fact that this is remotely exploitable, requires no authentication, and causes complete loss of availability.
Technical Information
Root Cause: Unhandled TypeError in URL Parsing
The vulnerability lives in the _requestHandler method of PrometheusExporter.ts. The exporter's built in HTTP server (bound to 0.0.0.0:9464 by default) processes incoming requests by parsing the request URL to determine if it matches the configured metrics endpoint path. The vulnerable code performed this parsing inline within a conditional expression:
// BEFORE (vulnerable) if ( request.url != null && new URL(request.url, this._baseUrl).pathname === this._endpoint ) { this._exportMetrics(response); } else { this._notFound(response); }
The request.url != null check guards against null or undefined values, but it does not protect against syntactically invalid URLs. This is where Node.js's HTTP parser behavior becomes relevant: it accepts absolute form URIs for HTTP proxy compatibility. When a client sends a request line like GET http:// HTTP/1.1, Node.js sets request.url to the string "http://". That string passes the null check, but when passed to the URL constructor, it throws a TypeError: Invalid URL.
Because there is no try...catch wrapping this call, the TypeError propagates up the call stack as an uncaught exception. In Node.js, an uncaught exception triggers the default behavior of printing the stack trace and terminating the process with a non zero exit code. The entire application dies, not just the metrics serving component.
This is classified as CWE-755: Improper Handling of Exceptional Conditions, an abstract weakness that manifests wherever error handling is incomplete around operations that can throw.
CVSS Vector Breakdown
The CVSS v3.1 vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H breaks down as follows:
| Component | Value | Meaning |
|---|---|---|
| Attack Vector (AV) | Network | Exploitable remotely |
| Attack Complexity (AC) | Low | No special conditions required |
| Privileges Required (PR) | None | No authentication needed |
| User Interaction (UI) | None | No user action needed |
| Scope (S) | Unchanged | Impact limited to the vulnerable component |
| Confidentiality (C) | None | No information disclosure |
| Integrity (I) | None | No data modification |
| Availability (A) | High | Complete loss of availability |
Attack Flow
The exploitation path is straightforward:
-
Identify the target: The attacker locates a Node.js service exposing the OpenTelemetry Prometheus metrics endpoint. The default configuration binds to
0.0.0.0:9464, meaning the endpoint is accessible on all network interfaces unless explicitly restricted. -
Send a malformed request: The attacker sends a single HTTP request containing an invalid absolute form URI. The request line
GET http:// HTTP/1.1is sufficient. -
Process termination: Node.js's HTTP parser accepts the request and sets
request.urlto"http://". TheURLconstructor throws aTypeError. The unhandled exception terminates the process. -
Cascading impact: In Kubernetes environments, the pod restarts. Repeated attacks can trigger CrashLoopBackOff conditions, degrading cluster performance through repeated pod scheduling and termination cycles. The loss of the metrics endpoint also blinds monitoring systems, potentially masking other malicious activity.
Default Binding Amplifies Exposure
The exporter binds to 0.0.0.0:9464 by default, which means it listens on all network interfaces. Services deployed without explicit host binding restrictions expose the metrics endpoint to any network the host is connected to. Aqua Security research has identified approximately 336,000 internet facing Prometheus servers and exporters, including roughly 296,000 exporters exposed to the public internet. While that figure covers all Prometheus infrastructure and not just OpenTelemetry JS instances specifically, it illustrates the scale of exposed telemetry endpoints.
Three Packages Affected
The vulnerability is not limited to the direct exporter package. Three npm packages carry the vulnerable code path:
| Package | How It Is Affected |
|---|---|
@opentelemetry/exporter-prometheus | Direct use via its built in HTTP server |
@opentelemetry/sdk-node | When OTEL_METRICS_EXPORTER includes prometheus |
@opentelemetry/auto-instrumentations-node | When loaded via --require or --import with Prometheus as the metrics exporter |
The @opentelemetry/auto-instrumentations-node package deserves special attention because it is commonly used for zero code instrumentation. Organizations may be running the vulnerable Prometheus exporter without being explicitly aware of it, since the package automatically configures exporters based on environment variables.
Proof of Concept
A public proof of concept is documented directly in the official GitHub Security Advisory (GHSA-q7rr-3cgh-j5r3), published by the OpenTelemetry JS maintainers on May 6, 2026.
Reproduction steps:
-
Start any Node.js application with the OpenTelemetry Prometheus exporter running on the default port 9464.
-
From any host that can reach the metrics port, send a single raw TCP packet containing a malformed HTTP request:
echo -ne 'GET http:// HTTP/1.1\r\nHost: localhost\r\n\r\n' | nc localhost 9464
- The target Node.js process crashes immediately with the following unhandled exception:
TypeError: Invalid URL
at new URL (...)
at PrometheusExporter._requestHandler (...)
The key insight is that Node.js's built in HTTP parser accepts absolute form URIs (like http://) for HTTP proxy compatibility. The string "http://" is a valid value for request.url from the parser's perspective, but it is not a valid URL from the URL constructor's perspective. This mismatch between what the HTTP parser accepts and what the URL parser rejects is the gap the vulnerability exploits.
No special tools, exploit kits, or authentication are required. A single unauthenticated network packet is sufficient for complete denial of service.
Patch Information
The OpenTelemetry maintainers addressed CVE-2026-44902 through Pull Request #6674, authored by @arminru (porting an original fix by @homanp). The PR was merged on May 6, 2026, by @pichlermarc and shipped in the experimental/v0.217.0 release the same day. The change touches a single file, PrometheusExporter.ts, with 11 additions and 4 deletions.
The patch restructures the logic by extracting the URL parsing into its own try...catch block, cleanly separating the error prone operation from the routing decision:
// AFTER (patched) let pathname: string | undefined; try { if (request.url != null) { pathname = new URL(request.url, this._baseUrl).pathname; } } catch { response.statusCode = 400; response.end('Bad Request'); return; } if (pathname === this._endpoint) { this._exportMetrics(response); } else { this._notFound(response); }
Instead of letting the TypeError crash the entire process, the catch block intercepts it, sets the HTTP response status code to 400 (Bad Request), writes a 'Bad Request' body, and returns early. The Node.js process remains fully intact and continues serving legitimate Prometheus scrape requests.
Fixed package versions:
| Package | Fixed Version |
|---|---|
@opentelemetry/exporter-prometheus | 0.217.0 |
@opentelemetry/sdk-node | 0.217.0 |
@opentelemetry/auto-instrumentations-node | 0.75.0 |
All versions prior to these are affected. The vulnerability existed from the very first version of the exporter. The relevant commit is e8f439a.
Affected Systems and Versions
The following npm packages are vulnerable in all versions prior to the specified fixed version:
@opentelemetry/exporter-prometheus: all versions before 0.217.0@opentelemetry/sdk-node: all versions before 0.217.0 (whenOTEL_METRICS_EXPORTERincludesprometheus)@opentelemetry/auto-instrumentations-node: all versions before 0.75.0 (when loaded with Prometheus as the metrics exporter via--requireor--import)
The vulnerable configuration is any Node.js application that runs the OpenTelemetry Prometheus exporter's built in HTTP server. The default configuration binds to 0.0.0.0:9464, but any custom host/port configuration is equally vulnerable since the root cause is in the request handler, not the binding configuration.
Vendor Security History
OpenTelemetry has a documented track record of vulnerability response. The CNCF graduation announcement explicitly states that "the OpenTelemetry community has addressed 12 CVEs since GA." Recent CVEs across the project reveal a pattern of denial of service vulnerabilities in exporter implementations:
| CVE ID | Component | Description | Severity |
|---|---|---|---|
| CVE-2026-44902 | opentelemetry-js (Prometheus exporter) | Process crash via malformed HTTP request | 7.5 (High) |
| CVE-2026-40891 | opentelemetry-dotnet (gRPC exporter) | DoS via unbounded grpc-status-details-bin header parsing | High |
| CVE-2026-24051 | opentelemetry-go | Path Hijacking (Untrusted Search Paths) on macOS/Darwin | Assigned |
The recurrence of DoS vulnerabilities across multiple language SDKs (JavaScript, .NET) suggests a systemic issue with error handling and input validation in OpenTelemetry exporter implementations. The CWE-755 classification of CVE-2026-44902 reinforces this: improper handling of exceptional conditions is a pattern that can manifest wherever error handling is incomplete. Organizations relying on OpenTelemetry should consider auditing all HTTP facing OpenTelemetry components for similar patterns and applying defense in depth beyond individual patches.
The project maintains a published security policy on GitHub and coordinates vulnerability disclosure through GitHub Security Advisories.
References
- NVD: CVE-2026-44902 Detail
- CVE.org: CVE-2026-44902 Record
- GitHub Security Advisory: GHSA-q7rr-3cgh-j5r3
- GitHub Advisory Database: GHSA-q7rr-3cgh-j5r3
- GitHub Advisory API: GHSA-q7rr-3cgh-j5r3
- OSV: GHSA-q7rr-3cgh-j5r3
- Fix PR #6674: opentelemetry-js
- Fix Commit: e8f439a
- Release: experimental/v0.217.0
- GitLab Advisory: @opentelemetry/exporter-prometheus
- GitLab Advisory: @opentelemetry/auto-instrumentations-node
- CWE-755: Improper Handling of Exceptional Conditions
- CNCF: OpenTelemetry Graduation Announcement
- Aqua Security: 300,000+ Prometheus Servers and Exporters Exposed to DoS Attacks
- Veracode: Prometheus Exporter Process Crash
- Snyk: @opentelemetry/exporter-prometheus
- OpenTelemetry JS GitHub Repository
- OpenTelemetry JS Security Policy
- OpenTelemetry CVE List



