milvus-io/milvus · error

HTTP error: ${resp.status}

Error message

HTTP error: ${resp.status}

What it means

Thrown when fetching /_telemetry/clients/{id}/history for historical metrics fails: the code first tries to parse the error body and use its 'error' field, falling back to 'HTTP error: {status}'. Unlike other calls, this one sends 'Authorization: Basic ${authToken}' - if authToken already contains the 'Basic ' prefix (as stored at login), the header becomes 'Basic Basic ...' and the server returns 401, surfacing as this error.

Source

Thrown at internal/http/webui/telemetry.html:2391

            if (diffMs >= 60 * 60 * 1000) {
                aggregate = true;
            }

            document.getElementById('historyModalContent').innerHTML = `
                <div class="empty-state" style="padding: 20px;">
                    <p>Loading historical metrics...</p>
                </div>
            `;

            try {
                const url = `${API_BASE}/_telemetry/clients/${encodeURIComponent(currentHistoryClientId)}/history?start_time=${encodeURIComponent(startTime)}&end_time=${encodeURIComponent(endTime)}&aggregate=${aggregate}`;
                const resp = await fetch(url, {
                    headers: { 'Authorization': `Basic ${authToken}` }
                });

                if (!resp.ok) {
                    const errData = await resp.json();
                    throw new Error(errData.error || `HTTP error: ${resp.status}`);
                }

                const data = await resp.json();

                // The endpoint returns a command_id since it's async
                // We need to wait for the command reply
                if (data.status === 'pending') {
                    document.getElementById('historyModalContent').innerHTML = `
                        <div class="empty-state" style="padding: 20px;">
                            <p>Command sent to client (ID: ${escapeHtml(data.command_id)})</p>
                            <p style="margin-top: 10px; color: var(--gray-500);">Results will be available in the client's next heartbeat.</p>
                            <p style="margin-top: 10px; color: var(--gray-500);">Waiting for client response...</p>
                        </div>
                    `;
                    pollForCommandReply(data.command_id, currentHistoryClientId, 'history', aggregate);
                    return;
                }

View on GitHub (pinned to b43a76673a)

Solutions

  1. Check devtools Network tab for the exact status: if 401 on every history call but other tabs work, the 'Basic ' prefix duplication is the cause - send the header the same way as other calls.
  2. For 400: verify start_time/end_time are valid epoch values with start < end and aggregate is a supported value.
  3. For 404: refresh the client list and retry against a live client.
  4. The server 'error' body field, when present, is already surfaced in the message - read it for the precise reason.

Example fix

// before
headers: { 'Authorization': `Basic ${authToken}` }

// after - match the header format used by every other telemetry call
headers: { 'Authorization': authToken }
Defensive patterns

Strategy: try-catch

Validate before calling

// build the header exactly once, same as all other telemetry calls
const headers = { 'Authorization': authToken }; // authToken already includes the scheme
const url = `${API_BASE}/_telemetry/clients/${encodeURIComponent(id)}/history?start_time=${encodeURIComponent(startTime)}&end_time=${encodeURIComponent(endTime)}&aggregate=${encodeURIComponent(aggregate)}`;

Try / catch

try {
  const resp = await fetch(url, { headers });
  if (resp.status === 401) { logout(); return; }
  if (!resp.ok) {
    const errData = await resp.json().catch(() => ({}));
    throw new Error(errData.error || `HTTP error: ${resp.status}`);
  }
} catch (e) { renderHistoryError(e.message); }

Prevention

When it happens

Trigger: Opening the metrics history modal with a malformed Authorization header (double 'Basic ' prefix) producing 401; unknown/evicted client_id producing 404; invalid time range or aggregate parameter producing 400 with an error body.

Common situations: Auth header construction inconsistent with the rest of the page (other fetches send authToken verbatim); expired or evicted client; start_time > end_time or unsupported aggregate value.

Related errors


AI-assisted analysis of milvus-io/milvus@b43a76673a (2026-08-15). Data as JSON: /api/errors/a7ba0bb3d062c37a. Report an issue: GitHub.