{"record":{"id":"eafa285a4c141e93","repo":"mastra-ai/mastra","slug":"http-response-status-response-statustext","errorCode":null,"errorMessage":"HTTP ${response.status}: ${response.statusText}","messagePattern":"HTTP (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/loggers/src/http/index.ts","lineNumber":82,"sourceCode":"\n  private async makeHttpRequest(data: any, retryCount = 0): Promise<Response> {\n    const controller = new AbortController();\n    const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n    try {\n      const body = JSON.stringify({ logs: data });\n\n      const response = await fetch(this.url, {\n        method: this.method,\n        headers: this.headers,\n        body,\n        signal: controller.signal,\n      });\n\n      clearTimeout(timeoutId);\n\n      if (!response.ok) {\n        throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n      }\n\n      return response;\n    } catch (error) {\n      clearTimeout(timeoutId);\n\n      if (retryCount < this.retryOptions.maxRetries) {\n        const delay = this.retryOptions.exponentialBackoff\n          ? this.retryOptions.retryDelay * Math.pow(2, retryCount)\n          : this.retryOptions.retryDelay;\n\n        await new Promise(resolve => setTimeout(resolve, delay));\n        return this.makeHttpRequest(data, retryCount + 1);\n      }\n\n      throw error;\n    }\n  }","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/loggers/src/http/index.ts#L64-L100","documentation":"makeHttpRequest() fetches the configured URL and throws 'HTTP <status>: <statusText>' when response.ok is false (any non-2xx status). The response body may contain more details, but this error surfaces the raw HTTP failure from the log ingestion endpoint.","triggerScenarios":"HttpTransport flushing log entries to an endpoint that returns 404 (wrong path), 401/403 (bad auth), 429 (rate limit), or 5xx (server error).","commonSituations":"Expired/invalid API key for the log collector; endpoint URL changed or includes a typo; collector rate-limiting under heavy log volume; transient server outages during _flush.","solutions":["Read the status in the error: fix 401/403 by updating credentials/headers, fix 404 by correcting the endpoint URL.","Implement retry with backoff for 429/5xx — the transport already has a timeout/abort mechanism you can build around.","Verify the endpoint accepts the POSTed JSON shape (array of log entries) and Content-Type: application/json."],"exampleFix":"// before: flush failures bubble up\nconst logger = new HttpTransport({ url: endpoint });\n// after: catch and retry transient statuses\ntry {\n  await logger.flush();\n} catch (e) {\n  if (/HTTP (429|5\\d\\d):/.test(e.message)) {\n    await new Promise(r => setTimeout(r, 2000));\n    await logger.flush();\n  } else throw e;\n}","handlingStrategy":"retry","validationCode":"function assertReachableEndpoint(url) {\n  const u = new URL(url);\n  if (u.protocol !== 'https:' && u.protocol !== 'http:') throw new Error('Log endpoint must be http(s)');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await logger.flush();\n} catch (e) {\n  const m = /HTTP (\\d{3}):/.exec(e.message);\n  if (m && ['429','500','502','503','504'].includes(m[1])) {\n    await backoffRetry(() => logger.flush(), 3); // exponential backoff\n  } else {\n    console.error('Log endpoint rejected request:', e.message);\n  }\n}","preventionTips":["Monitor the 2xx status of your log ingestion endpoint and alert on 4xx/5xx.","Keep collector credentials fresh and rotate them before expiry.","Throttle log volume to stay under collector rate limits."],"tags":["network","http","logging","retry"],"backgroundTag":"http-request-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}