louislam/uptime-kuma · error · Error

Failed to fetch measurement (${res.data.id}): ${this.formatA

Error message

Failed to fetch measurement (${res.data.id}): ${this.formatApiError(measurement.data.error)}

What it means

Thrown after createMeasurement succeeds but awaitMeasurement(id) returns non-ok. The measurement was accepted (res.data.id exists) yet polling for its completion failed, typically due to a Globalping server-side error, timeout on the awaiting loop, or the measurement id becoming inaccessible. The original id is embedded for correlation.

Source

Thrown at server/monitor-types/globalping.js:109

        let res = await client.createMeasurement(opts);

        // Retry if the server returns a 500 error
        if (!res.ok && Globalping.isHttpStatus(500, res)) {
            res = await client.createMeasurement(opts);
        }

        if (!res.ok) {
            if (Globalping.isHttpStatus(429, res)) {
                throw new Error(`Failed to create measurement: ${this.formatTooManyRequestsError(hasAPIToken)}`);
            }
            throw new Error(`Failed to create measurement: ${this.formatApiError(res.data.error)}`);
        }

        log.debug("monitor", `Globalping fetch measurement: ${res.data.id}`);
        let measurement = await client.awaitMeasurement(res.data.id);

        if (!measurement.ok) {
            throw new Error(
                `Failed to fetch measurement (${res.data.id}): ${this.formatApiError(measurement.data.error)}`
            );
        }

        const probe = measurement.data.results[0].probe;
        const result = measurement.data.results[0].result;

        if (result.status === "failed") {
            throw new Error(this.formatResponse(probe, `Failed: ${result.rawOutput}`));
        }

        if (!result.timings?.length) {
            throw new Error(this.formatResponse(probe, `Failed: ${result.rawOutput}`));
        }

        heartbeat.ping = result.stats.avg || 0;
        heartbeat.msg = this.formatResponse(probe, "OK");
        heartbeat.status = UP;

View on GitHub (pinned to 6b5ea01557)

Solutions

  1. Inspect the embedded error (formatApiError output) for the specific failure.
  2. Retry the monitor check; transient await failures usually clear on the next heartbeat.
  3. If recurring, check status.globalping.io and reduce measurement complexity (fewer packets, simpler target).
  4. Correlate the printed measurement id with Globalping dashboards if available.
Defensive patterns

Strategy: retry

Try / catch

try {
  await gp.monitor(client, monitor, heartbeat, hasToken);
} catch (e) {
  if (/Failed to fetch measurement/.test(e.message)) { heartbeat.status = PENDING; heartbeat.msg = e.message; return; }
  throw e;
}

Prevention

When it happens

Trigger: Globalping accepts the create call and returns an id, then the polling endpoint returns an error status (5xx during probe execution, or a 404 if the id was purged). awaitMeasurement returns {ok:false} with data.error.

Common situations: Probe-side failure cascading into the status endpoint; Globalping platform incident mid-measurement; long-running measurements hitting the await timeout; account/credit state changing between create and poll.

Related errors


AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12). Data as JSON: /api/errors/b35934aa17722bdd. Report an issue: GitHub.