The application runs in the system tray, manages configuration and logging, and automatically updates the configured client's listening port when changes are detected. It also includes a Media Manager for importing files into Plex-compatible library folders using TMDB title matching.
All options install the same application. New versions appear on the GitHub release page first; the package managers follow once the new version clears their moderation.
Built into Windows 10/11, no extra tooling needed.
Run from an elevated prompt.
-
Automatic Port Sync
Detects the current VPN port and updates the client's listening port automatically. Supports qBittorrent (Web API), Transmission (RPC), Deluge (Web JSON-RPC), and Nicotine+ (via a bridge plugin qbPortWeaver installs for you). Nicotine+ applies the change to the running client, so its port follows the VPN without a restart.
-
Sync on Network Change
In addition to the scheduled interval, qbPortWeaver can run a sync the moment a network or VPN connection change is detected, so the client follows a VPN reconnect within seconds instead of waiting for the next cycle. Rapid changes are coalesced into a single sync, and pausing still suppresses it. Enabled by default; configurable via Settings → General.
-
Multi-VPN Support
Supports ProtonVPN (via log file parsing or NAT-PMP), PIA (via piactl CLI), and any NAT-PMP capable VPN gateway or router (via RFC 6886 port mapping, requested for both TCP and UDP). Configurable through the Settings dialog.
-
Default Port Fallback
When VPN is not connected, optionally sets the client's listening port to a configured default. Useful if you have a port forwarded in your router for direct connections without VPN.
-
Wait for VPN at Startup
For a short grace period after the app starts, a VPN that is still connecting is treated as expected rather than a failure: the tray stays neutral, no warning is logged, and the default-port fallback and auto-recovery are held. The port syncs as soon as the VPN comes up. Enabled by default; configurable via Settings → General.
-
Restart After Port Change
Optionally restart the client after updating the port to ensure changes take effect immediately. Nicotine+ needs no restart - its plugin applies the port to the running client - so it has no such setting.
-
Force-Start
Optionally launch the client automatically if it is not running.
-
Restart on Disconnect (qBittorrent only)
Optionally restart qBittorrent when its connection status changes to disconnected. Requires the Executable and Process name to be configured. Restarts stop after three consecutive attempts that do not clear the disconnect, since a cause the client keeps in its own configuration cannot be fixed by restarting; they resume automatically once it reconnects.
-
Port Verification
After each sync, optionally checks that the listening port is actually reachable from the Internet - not just configured. Runs after a port change and periodically (every 5th cycle); a closed result is confirmed on the next cycle before a warning is logged and a tray notification is shown. Transmission and Deluge use their projects' online port checkers; qBittorrent infers reachability from incoming connections, so an idle client may report closed. Nicotine+ is checked through its bridge plugin: it uses Nicotine+'s own native port checker when the version has one, and otherwise queries the Soulseek port-test service directly, so reachability works on current releases too. Enabled by default.
-
Pause and Resume Syncing
A Pause Syncing item in the tray menu temporarily stops sync cycles (including Media Manager imports) without changing any settings. While paused, Sync Port Now still runs a single cycle on demand. Syncing always resumes when the application restarts.
-
VPN Interface Mismatch Warning (qBittorrent and Nicotine+)
Shows a tray balloon tip and logs a warning if the client's network interface does not match the configured VPN provider, or if it is bound to all interfaces (which may cause traffic leaks). Transmission and Deluge report a bind address rather than an adapter name, so there is no name to compare and the check does not apply to them.
-
Stale Interface Binding Detection (qBittorrent only)
qBittorrent stores its network interface as an internal identifier as well as a name. When a VPN destroys and recreates its adapter the identifier stops resolving while the name still reads correctly, so qBittorrent listens on nothing and a restart cannot fix it - the value is in its own configuration. qbPortWeaver checks the identifier against qBittorrent's live adapter list each cycle and warns when it has gone stale. Fix the network interface binding when it goes stale re-applies it automatically, restoring the adapter you selected. Enabled by default; turn it off to be warned instead.
-
Port Update Notification
Optionally shows a tray balloon tip when the client's listening port is successfully updated to a new value. Enabled by default. Configurable via Settings → General.
-
Log Alert Notifications
When a warning or error is logged, a one-shot tray balloon appears; clicking it opens the log viewer at the latest issue. The Show Logs item and the tray tooltip show a running warning/error count, which clears when you open the log viewer or clear the logs.
-
Auto-Recovery
After a configurable number of consecutive failed cycles (VPN disconnected, or connected but no port assigned), recovery runs through a lightweight helper service (qbPortWeaverHelper, LocalSystem, no UAC): for ProtonVPN/PIA it restarts the VPN service and client; for a generic NAT-PMP gateway it cycles the adapter via netsh. Recovery is also held until the failures have persisted long enough, so a brief blip raced through by network-change re-syncs does not force a restart. A second, independent trigger runs the same recovery when port verification confirms the port closed for a set number of checks (on by default; requires Check that the forwarded port is open after each sync); it fires once and re-arms only when a scheduled check reports the port open again. Use with care on qBittorrent, where an idle client can report closed indefinitely. A Test button next to the Auto-recovery settings runs the recovery action on demand (after a confirmation), so the whole chain can be verified before a real failure needs it.
Recovery is rate-limited while an internet connection cannot be confirmed, since restarting a VPN cannot restore a connection that is down upstream. Reachability is checked by pinging public DNS resolvers; when nothing answers, the first recovery of a streak still runs and later attempts are spaced out to 5, 10 and then 15 minutes until connectivity returns. It is deliberately a rate limit rather than a block: a VPN killswitch also blocks those pings while the tunnel is down, so refusing to recover outright would leave exactly the users who need a restart unable to get one.
-
Post-Update Command
Optionally run a custom command after a successful port update (fire-and-forget). See SampleSendMail.ps1 for an example of sending an email notification with status details.
-
Media Manager
Imports movie and TV episode files into Plex-compatible library folders each cycle, using TMDB for titles and years and Plex naming (Title (Year).ext, Show (Year) - SxxExx.ext, multi-episode SxxExxExx) via hardlink (falling back to copy across volumes), copy, or move. Beyond the SxxExx pattern, episodes in season subfolders with numbered filenames (Show/Season N/01-Title.mp4) are recognised too (English, French, Spanish, and Italian season indicators). It can create Plex subfolders (Movies/Title (Year)/, TV Shows/Show (Year)/Season XX/) and delete emptied source folders (including .nfo-only ones).
A dedicated Media Manager dialog (tray menu → Media Manager) configures source and library folders, previews imports (Scan Now), and applies or corrects them (Import Now), highlighting uncertain TMDB matches. A free TMDB API key is required.
-
Tray Icon Interface
Runs quietly in the background with a system tray icon for quick access to logs, settings, and controls.
-
Tray Status Indicator
After each sync cycle the tray icon shows a colored status dot: green (ports aligned), orange (VPN not connected), red (error), gray (sync paused), or no dot (port sync disabled, or waiting during the startup grace period). Hovering over the icon displays the current port and status, and an unviewed log count if warnings or errors have occurred (e.g. "2 Warnings, 1 Error").
-
Status Panel
A Status window (tray menu → Show Status, or double-click the tray icon) shows the live sync chain at a glance: VPN provider and connection, an auto-recovery line covering both triggers (how close each is to firing, or why it is holding off), forwarded port, client and whether it is running, listening port (with an in-sync indicator), reachability (with how long ago it was last checked), the last sync time and result, and an estimate of the next sync. Color accents flag anything out of sync, closed, or in error. A Recent Port Changes list shows the latest port assignments, confirmed-closed results, and auto-recovery actions with timestamps, kept across restarts (right-click the list to clear it); port changes note their cause when a network change or a recovery prompted them. A Statistics section summarizes stability at a glance: the current port, how many times it changed today, and this session's sync and auto-recovery counts (manual recovery tests are not counted; right-click the section to reset the session counters). The panel refreshes after each cycle and updates its live timers every second. A Sync Now button runs an immediate cycle, Pause/Resume stops or restarts automatic cycles (the same toggle as the tray menu), Test Port checks reachability on demand, and Run Diagnostics health-checks the whole chain.
-
Diagnostics
A Run Diagnostics action (Status panel and tray menu) runs a read-only health check across the whole sync chain and shows a pass/warning/fail checklist with a fix hint for each step: configuration, helper service, internet connectivity, VPN connection and forwarded port, client running, client plugin (Nicotine+ only), client reachable, ports in sync, interface binding (qBittorrent and Nicotine+), client settings, and outside reachability. The client plugin check appears only when Nicotine+ is the selected client and reports what state the bridge plugin is in: not installed, installed but not enabled, installed but never started, out of date, or connected on an address that differs from your saved settings. Those all look identical from the reachability check alone but need different fixes, so the row names which one you have and what to do about it. The internet connectivity check reports whether this machine gets a reply when it pings public DNS resolvers, which is what auto-recovery uses to decide whether to attempt a restart immediately or space its attempts out. A warning here does not necessarily mean anything is broken: a network that filters ping, or a VPN killswitch blocking traffic while the tunnel is down, both produce it with the connection otherwise working. It is worth knowing either way: when auto-recovery is enabled this is what spaces out repeat attempts, and Diagnostics is the only place you can check it on demand rather than waiting for a recovery to be held. The client settings check looks for options in the client itself that undo the forwarded port - a randomised listening port, or the client's own UPnP/NAT-PMP forwarding. qbPortWeaver switches these off every time it sets the port, so a warning here means one was turned back on since; it names the option as the client's own settings screen labels it. On Transmission and Nicotine+ this is the only check that can see the problem: the client keeps reporting the correct port, so nothing looks wrong until it is next restarted. The same check also runs periodically during normal syncing and raises a tray warning when one of these options is switched on, so it is caught without having to run Diagnostics. Re-run refreshes it and Copy Report puts the results on the clipboard for a support request. It never changes the port or restarts anything.
-
Settings Dialog
All configuration options are editable through a dedicated Settings form (tray menu → Settings), organised into General, Client, Auto-Recovery, and Extra tabs, with inline descriptions and tooltips for each option. A Detect button on the General tab finds a running or installed client (qBittorrent, Transmission, Deluge, or Nicotine+) and fills in its selection and process details, asking you to choose when more than one is found. A second Detect button does the same for the VPN provider, selecting ProtonVPN or PIA when its service is present on the machine. NAT-PMP gateways are not machine-local and so cannot be detected; select NAT-PMP yourself if that is what you use.
-
Back Up and Restore Settings
Back Up… on the Settings dialog saves your configuration to a JSON file, and Restore… reads it back, so a reinstall or a move to another PC does not mean setting everything up again by hand. Every setting is included, along with the VPN provider details stored alongside them (service names, adapter names, client process names and the ProtonVPN log path). Passwords, the Nicotine+ token and the TMDB API key are not, because Windows encrypts them to one user account on one machine: a restore leaves those exactly as they were, and tells you to re-enter them if the backup came from elsewhere. Backing up saves the dialog once you have chosen where to put the file, so what you see on screen is what lands in it. A restore replaces your current settings and cannot be undone, so it confirms first. Individual entries this version does not recognise are skipped and counted rather than rejecting the whole file; a backup whose format is newer than this build understands is refused outright, leaving your settings untouched.
-
Support Bundle
Save Support Bundle… in the Diagnostics window collects everything a support request needs into one zip: the diagnostics report as shown, a settings snapshot covering every section and the values stored alongside them, the current log with its rotated backups, the status file and the port history. Assembling that by hand is easy to get wrong, because the log rotates and the window that explains a problem may already have moved into a backup file. Passwords, tokens and API keys are masked, and the key names are kept so the report still shows which settings are present.
-
Connection Test
Each client section in Settings has a Test button next to the URL. It checks the connection to the selected client using the values currently entered (no need to save first), then reports success along with the current listening port, or points you to the log if it cannot connect.
-
Log Viewer
Built-in log viewer (tray menu → Show Logs) displays the log file with color-coded entries by level (error, warn, info, debug) and follows new entries in real time. Includes a search bar with match highlighting and prev/next navigation, dedicated prev/next buttons to step between warnings and errors without affecting the search, toggle buttons to filter by log level, a subsystem filter to isolate entries from a specific component, a time filter to narrow the view to the last 15 minutes, hour or 24 hours, or to a custom start and end time, and a file picker to browse rotated backup files. The view is virtualized, so filters apply instantly and scrolling stays smooth even on very large logs, and the viewer keeps a low, steady memory footprint when left open for days. Adapts to the application color theme (System, Dark, or Light).
-
Consistent Theming
All windows - Settings, Status, Diagnostics, the log viewer, Media Manager, and the tray menu - follow your chosen color theme (System, Dark, or Light) uniformly, using the native Windows colors so text and surfaces stay legible in both light and dark mode. Confirmation and alert pop-ups are themed to match, so they no longer appear in bright white in dark mode.
-
Logging
Logs all operations and errors, with automatic log size management (20 MB per file, up to 5 files total). Clear logs directly from the tray menu.
-
Last-Run Status File
Writes a JSON status file (%LocalAppData%\qbPortWeaver\qbPortWeaver.status.json) after each sync cycle, exposing VPN port, client port, timestamps, and completion status for external scripts.
-
Automatic Update Checker & In-App Update
Checks GitHub for new releases on startup and every 12 hours, surfacing a newer version via an Update available (X.Y.Z) tray item and tooltip (the 12-hour check is non-intrusive; the startup form can be turned off under Settings → General). A Check for Updates item checks on demand and always reports a result. When an update is available, the update window offers Download & Install - it downloads the installer, runs it, and the app relaunches when the update finishes (falling back to the release page if anything goes wrong). The About dialog shows the current and latest version, update status, contributor links, and a What's New button.
-
Built-in User Guide
A Help item in the tray menu opens this user guide in a built-in viewer with a browsable table of contents, text search (Ctrl+F with match navigation), formatted headings, tables, and clickable links - no browser or internet connection needed.
-
Startup Option
Allows enabling or disabling automatic startup with Windows.
NAT-PMP (RFC 6886) is a protocol for requesting port mappings directly from a gateway. qbPortWeaver supports it in two scenarios:
> If no adapter appears in the list, ensure the adapter is up and its gateway is responding to NAT-PMP, then click the ⟳ button to refresh without reopening Settings.
Nicotine+ has no remote-control interface, so qbPortWeaver talks to it through a small bridge
plugin. Everything below is a one-off; after it, port sync is fully automatic and the port changes
without restarting Nicotine+.
The application is designed to always recover. A failing cycle never crashes the app; errors are logged and the loop retries on the next interval.
Some problems sit outside the sync loop and used to pass unnoticed. Each of these now says so:
Versions before 2.2.0 predate the current architecture - four clients, NAT-PMP, the helper
service and the Media Manager all arrived later - and are recorded in the git history rather
than here.
Free of use and distribution. No warranty provided.
This applies to qbPortWeaver itself. The Nicotine+ bridge plugin under plugins/ is a separate work licensed GPL-3.0-or-later and carries its own LICENSE file, which travels with it when the plugin is installed.