agalwood/Motrix · error · HttpError

plugin.http.network

plugin.http.network

Error message

Network error: ${err instanceof Error ? err.message : String(err)}

What it means

Catch-all for non-abort failures from undiciRequest: DNS errors (ENOTFOUND, EAI_AGAIN), connection refused (ECONNREFUSED), TCP resets (ECONNRESET), socket hang-up, TLS/cert errors, invalid HTTP responses, and similar. The underlying message is interpolated so callers can branch on the cause while keeping one stable error code.

Source

Thrown at src/core/plugin/capabilities/http.ts:358

              throw new HttpError(
                'plugin.http.aborted',
                'Request aborted by plugin'
              )
            }
            throw new HttpError('plugin.http.aborted', 'Request aborted')
          }
          if (
            err instanceof Error &&
            (err.name === 'AbortError' ||
              err.name === 'DOMException' ||
              err.constructor?.name === 'DOMException')
          ) {
            throw new HttpError(
              'plugin.http.aborted',
              'Request aborted by plugin'
            )
          }
          throw new HttpError(
            'plugin.http.network',
            `Network error: ${err instanceof Error ? err.message : String(err)}`
          )
        }

        // Capture cookies from response on this hop.
        if (useCookies && this.cookieJar) {
          const rawSetCookie = response.headers['set-cookie']
          const arr = Array.isArray(rawSetCookie)
            ? rawSetCookie
            : typeof rawSetCookie === 'string'
              ? [rawSetCookie]
              : []
          if (arr.length > 0) {
            this.cookieJar.captureFromResponseHeaders(currentUrl, arr)
          }
        }

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Inspect err.message / cause for the specific syscall (ENOTFOUND vs ECONNRESET vs CERT_*).
  2. Verify host, port, and DNS resolution from the runtime environment.
  3. For TLS errors, validate the CA chain and system clock.
  4. Configure proxy/HTTP_PROXY/HTTPS_PROXY if applicable.
  5. Retry with backoff for transient resets.
Defensive patterns

Strategy: retry

Type guard

function isTransientNetwork(err: unknown): boolean {
  if (!(err instanceof HttpError)) return false
  if (err.code !== 'plugin.http.network') return false
  return /ECONNRESET|ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|socket hang up/i.test(err.message)
}

Try / catch

for (const attempt of [1,2,3]) {
  try {
    return await http.request(opts)
  } catch (e) {
    const transient = e instanceof HttpError && e.code === 'plugin.http.network'
    const dns = e instanceof HttpError && /ENOTFOUND|EAI_AGAIN/.test(e.message)
    if (transient && !dns && attempt < 3) { await sleep(2 ** attempt * 200); continue }
    throw e
  }
}

Prevention

When it happens

Trigger: DNS resolution failure; target host/port unreachable; TLS certificate invalid/expired/self-signed; connection reset mid-transfer; server returned malformed HTTP; proxy refused the CONNECT.

Common situations: Wrong hostname in config; firewall or network partition; clock skew causing TLS cert validity mismatch; corporate proxy not configured; IPv6-only target with no v6 route.

Related errors


AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12). Data as JSON: /api/errors/434481e0b569fef3. Report an issue: GitHub.