diegosouzapw/OmniRoute · error · Error

TPROXY capture mode requires the native addon (Linux +…

Error message

TPROXY capture mode requires the native addon (Linux + CAP_NET_ADMIN).

What it means

Dependency guard in startCaptureMode: the injected deps report the native TPROXY addon is unavailable. The addon requires Linux and CAP_NET_ADMIN (transparent-proxy socket options plus netfilter rule manipulation), so this fires when running on the wrong platform, without root/capabilities, or with the native module not built/loaded — capture mode cannot run at all in this environment.

Solutions

  1. Run the server on Linux with CAP_NET_ADMIN (or as root)
  2. Rebuild/reinstall the native TPROXY addon if it failed to compile or load
  3. Fall back to the userspace MITM HTTP proxy mode when the addon can't be provided
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/mitm/tproxy/captureManager.ts:78 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of diegosouzapw/OmniRoute@a179ffed5b (2026-08-25). Data as JSON: /api/errors/577a4238aca5aaf9. Report an issue: GitHub.

Appendix: source

Thrown at src/mitm/tproxy/captureManager.ts:78

  startedAt: string;
  intercepts: { count: number };
}

let active: ActiveCapture | null = null;

/**
 * Start the decrypt-capable TPROXY capture mode. Rejects if a session is already
 * running or the native addon is unavailable. The dynamic CA is created here and
 * installed in the trust store via the injected `installCa`.
 */
export async function startCaptureMode(
  options: StartCaptureModeOptions
): Promise<CaptureManagerStatus> {
  if (active) throw new Error("TPROXY capture mode is already running");

  const deps: CaptureManagerDeps = { ...realDeps, ...options.deps };
  if (!deps.isAvailable()) {
    throw new Error("TPROXY capture mode requires the native addon (Linux + CAP_NET_ADMIN).");
  }

  const certStore = deps.createCertStore();
  const intercepts = { count: 0 };
  const handle = await deps.startTproxyCapture(options.cfg, {
    decrypt: { certStore, installCa: options.installCa, uninstallCa: options.uninstallCa },
    onIntercept: () => {
      intercepts.count += 1;
    },
  });
  active = { handle, startedAt: deps.now(), intercepts };
  return getCaptureStatus();
}

/** Stop the running capture session (closes the listener, uninstalls the CA, and
 * reverts the rules via the handle). Idempotent — a no-op when nothing runs. */
export async function stopCaptureMode(): Promise<CaptureManagerStatus> {
  const current = active;

View on GitHub (pinned to a179ffed5b)