Blog Engineering

When GET Heartbeats Hit the Dashboard: A One-Line OneUptime Routing Fix

Articolo in inglese. On self-hosted OneUptime, GET heartbeat requests returned Dashboard HTML. One reserved route prefix sends them back to the ingest handler.

TypeScriptOneUptime/oneuptimemonitoringroutingself-hosting

A self-hosted monitoring bug where the fix was a single line, merged two hours after the PR was opened.

Risposta breve

On self-hosted OneUptime, a GET to an Incoming Request Monitor's heartbeat URL returned the Dashboard's HTML instead of registering the heartbeat, so the monitor stayed offline. POST worked. The fix reserves the /incoming-request path so the Dashboard's single-page-app fallback no longer catches it. It was merged as PR #3316 and closed issue #2986.

The problem

OneUptime is an open-source observability and monitoring platform. Issue #2986, reported on version 11.7.2 deployed with the official Helm chart, showed that:

curl --include "https://<oneuptime-host>/heartbeat/<secretkey>"

returned HTTP/2 200 with Content-Type: text/html and the Dashboard app, while the same URL with --request POST reached the ingest handler and returned {}. As the reporter noted, the documented GET examples, including plain curl cron jobs, did not work on affected versions.

Root cause

According to the PR, nginx rewrites /heartbeat to /incoming-request. The Dashboard registers a catch-all GET fallback for its single-page app, skipping a list of reserved prefixes. /incoming-request-ingest was on that list, but /incoming-request was not, so GET heartbeats were served the Dashboard.

The fix

   "/session-replay",
   "/incoming-request-ingest",
+  "/incoming-request",
   "/otlp",

By the numbers

  • Repository: OneUptime/oneuptime, 7,785 stars (Nov 3, 2026), TypeScript. Apache-2.0 outside the ee/ directory, per the project's NOTICE file
  • Files changed: 1
  • Lines: +1 / -0
  • Commits: 1
  • Opened: Aug 21, 2026. Merged: Aug 21, 2026. Time to merge: 2 hours, 5 minutes
  • Review: merged by a maintainer; automated security checks passed

How the review went

There was no review discussion. A maintainer merged the change about two hours after it was opened, and the issue closed with it.

Domande frequenti

Did this include the claimed regression test?

The PR description claimed a regression test, but the merged diff adds only the route prefix and contains no test. No human review discussion is recorded.

Do POST heartbeats change?

No. POST already reached the ingest handler. The change only stops the Dashboard fallback from intercepting GET.

Where can I read more?

See the pull request and the original issue.

L'obiettivo

The issue was detailed, and the cause sat in one list of route prefixes. Finding the right line is most of the work, and a one-line change is about as reviewable as a fix gets.

Esegui il ciclo

Trasforma i segnali di produzione in fix revisionati.

Avvia una prova gratuita e scopri come Prilog collega incidenti reali a pull request a livello di codice.