Prerequisites
Server Hardware
Lenovo M920q 32gb RAM 2 TB M.2
StartOS Version
0.4.0
Client OS
MacOS
Client OS Version
15.7.7
Browser
Firefox
Browser Version
Version 152.0.5 (64-bit)
Current Behavior
Current Behavior
On a VPS behind 1:1 NAT (where the public IPv4 is assigned at the provider edge and not bound to any local interface—the typical AWS, Oracle, GCP, or Azure model), no new port forwards can be created via the CLI or web UI after upgrading. Both setup paths fail identically:
- CLI:
$ sudo start-tunnel port-forward add --label "LND" 9735 10.59.203.3:9735
Network Error: no WAN IP available for device 10.59.203.3
- Web UI (Add published port, IPv4):
RPC ERROR: Network Error no WAN IP available for device 10.59.203.3
Two independent defects combine to make this state entirely unrecoverable for the end user:
Defect A: The subnet wanIp is null after migration
A db dump reveals that wanIp is explicitly null on the gateway, the subnet, and every downstream device. This occurs even though get-available-ips actively returns a perfectly usable local interface IP (172.16.0.12).
While all relevant port-forward schema migrations successfully executed (PortForwardAuto, PortForwardEntry, PortForwardKind, ReclaimPort80Redirect, WgClientKind), none of them backfilled the new wanIp field. Port forwards that existed prior to the upgrade continue to function normally because they carry the external IP embedded directly in their entry keys, allowing their DNAT rules to remain present and pass traffic. As a result, only new additions fail.
Defect B: subnet … set-wan is uninvokable
The subnet ... set-wan CLI administrative command—which is intended to manually correct a missing wanIp—is broken at the argument-parsing level. Its own --help page emits a duplicate <SUBNET> positional argument:
Usage: start-tunnel subnet <SUBNET> set-wan [OPTIONS] <SUBNET>
Because both the parent subnet <SUBNET> argument and the nested set-wan <SUBNET> argument attempt to deserialize into the exact same database key structure, any physical command invocation fails:
- Providing the subnet once:
error: the following required arguments were not provided: <SUBNET>
- Providing the subnet twice:
General error: error: Serialization Error: duplicate key: subnet
Consequently, there is no valid structural syntax to invoke this command.
Absence of Workaround
Direct manual patching via db apply is entirely blocked. The utility expects an undocumented, jq-like expression format (where the parser enforces tokens like def / if / ( / [ / .. / { / - / .).
Neither a broad full-document replacement nor a hyper-targeted JSON-pointer operation will validate against the internal structural model, consistently resulting in schema rejection messages:
missing field 'webserver': result does not match database model
As it stands, end users hosting on a NAT'd cloud VPS have zero supported paths to manually or programmatically set wanIp.
Expected Behavior
Proposed Solutions & Fixes
1. Fix CLI Argument Inheritance for set-wan
The set-wan command must correctly inherit the <SUBNET> positional argument from its parent context without requiring a second, duplicate positional argument at the tail.
- Target Syntax:
subnet <SUBNET> set-wan --wan-ip <IP>
- Expected Action: Inherit the
<SUBNET> parameter and successfully update the subnet's WAN IP.
2. Backfill wanIp via Migration
The database upgrade migration routine must be updated to prevent existing installations from entering an unusable state.
- Detection Logic: Automatically scan and extract the
wanIp from the active network interface.
- Fallback Logic: If interface detection is blocked, extract and backfill the
wanIp using the embedded IP addresses found inside legacy port-forward entries.
3. Implement Fallback Resolution for Port Forwarding
Both the CLI port-forward add command and the Web UI Add published port dialog must support NAT'd VPS setups.
- Dynamic Lookup: If the
wanIp state field evaluates to null, the application must query get-available-ips to dynamically resolve it.
- Validation Rule: Prevent hard-failing with a network error when the necessary IP configuration data is already discoverable on the system.
Steps to Reproduce
Steps to Reproduce
1. Confirm Environment and Available Interfaces
Run StartTunnel 1.2.1 on a Debian 13 VPS whose public IPv4 is NAT'd and not present on the NIC (only a private IP on the interface).
$ ip -4 addr show
2: ens3: ... inet 172.16.0.12/20 ... scope global dynamic ens3
$ sudo start-tunnel web get-available-ips
[ "172.16.0.12", "<global-IPv6>", "<link-local-IPv6>", "127.0.0.1", "::1" ]
2. Attempt to Add Port Forward via CLI
Try to add a port forward using the command-line interface.
$ sudo start-tunnel port-forward add --label "LND" 9735 10.59.203.3:9735
Verbatim Error:
Network Error: no WAN IP available for device 10.59.203.3
3. Attempt to Add Port Forward via Web UI
Navigate to Port Forwards → Add published port and enter the details:
- Protocol: IPv4
- External Port: 9735
- Internal Port: 9735
- Target: Server device
Verbatim Error:
RPC ERROR: Network Error no WAN IP available for device 10.59.203.3
4. Attempt to Set Subnet WAN IP (Both Forms Fail)
Try to manually set the subnet WAN IP so the forward can resolve. Both syntax forms fail to invoke properly.
Form A (Missing argument error):
$ sudo start-tunnel subnet 10.59.203.1/24 set-wan --wan-ip 172.16.0.12
Verbatim Error:
error: the following required arguments were not provided:
<SUBNET>
Form B (Duplicate key error):
$ sudo start-tunnel subnet 10.59.203.1/24 set-wan --wan-ip 172.16.0.12 10.59.203.1/24
Verbatim Error:
General error: error: Serialization Error: duplicate key: subnet
Anything else?
System Diagnostics & Impact Assessment
📋 Full Environment Profile
- Component: StartTunnel 1.2.1
- Update Verification:
{"status":"up-to-date","installed":"1.2.1","candidate":"1.2.1"}
- Installation Protocol: Upgraded from legacy 0.x/1.0.x line via:
curl -sSL https://start9.com/start-tunnel/install.sh | sh
- Network Topology: 1:1 NAT Cloud VPS (Public IPv4 at provider edge; local interface
ens3 bound to private IP 172.16.0.12/20). Matches standard documentation models for AWS EC2, Oracle Cloud, GCP, and Azure.
- Subnet Layout: One active subnet (
10.59.203.1/24) containing one StartOS server device (10.59.203.3) and three downstream clients.
🗄️ Database Evidence (db dump Analysis)
A redacted look at the post-migration database state shows exactly where state validation collapses. Existing entries remain functional due to inline legacy keys, while the new wanIp parent tracking keys remain explicitly empty:
💥 Severity & Scope of Impact
Port forwarding configuration is fundamentally broken across all virtual private servers operating behind an edge NAT layout (including AWS, Azure, GCP, and Oracle Cloud).
Because pre-existing DNAT rules continue to pass traffic perfectly, the underlying translation layer remains healthy. The failure is strictly administrative: the software blocks new additions when wanIp is null, yet provides no valid command sequence to populate it.
🛠️ Recommended Code Fixes
- Fix CLI Argument Inheritance: Remove the redundant trailing
<SUBNET> positional argument requirement from the set-wan command structure. Allow it to natively inherit context from the parent subnet command space.
- CLI Sub-Command Audit: Audit sister sub-commands (specifically
set-dns and set-ipv6) to ensure this duplicate positional parameter defect is not replicated across other network configuration modules.
- Enhance Migration Routine: Update database migration logic to automatically backfill the
wanIp data property using either the active interface IP or values parsed from legacy pre-upgrade port-forward records.
- Implement Port Forwarding Fallbacks: Modify the validation check within the
port-forward add sequence. If wanIp resolves to null, fallback to query get-available-ips dynamically instead of executing an immediate hard failure.
Prerequisites
Server Hardware
Lenovo M920q 32gb RAM 2 TB M.2
StartOS Version
0.4.0
Client OS
MacOS
Client OS Version
15.7.7
Browser
Firefox
Browser Version
Version 152.0.5 (64-bit)
Current Behavior
Current Behavior
On a VPS behind 1:1 NAT (where the public IPv4 is assigned at the provider edge and not bound to any local interface—the typical AWS, Oracle, GCP, or Azure model), no new port forwards can be created via the CLI or web UI after upgrading. Both setup paths fail identically:
Two independent defects combine to make this state entirely unrecoverable for the end user:
Defect A: The subnet
wanIpis null after migrationA
db dumpreveals thatwanIpis explicitlynullon the gateway, the subnet, and every downstream device. This occurs even thoughget-available-ipsactively returns a perfectly usable local interface IP (172.16.0.12).While all relevant port-forward schema migrations successfully executed (
PortForwardAuto,PortForwardEntry,PortForwardKind,ReclaimPort80Redirect,WgClientKind), none of them backfilled the newwanIpfield. Port forwards that existed prior to the upgrade continue to function normally because they carry the external IP embedded directly in their entry keys, allowing their DNAT rules to remain present and pass traffic. As a result, only new additions fail.Defect B:
subnet … set-wanis uninvokableThe
subnet ... set-wanCLI administrative command—which is intended to manually correct a missingwanIp—is broken at the argument-parsing level. Its own--helppage emits a duplicate<SUBNET>positional argument:Because both the parent
subnet <SUBNET>argument and the nestedset-wan <SUBNET>argument attempt to deserialize into the exact same database key structure, any physical command invocation fails:Consequently, there is no valid structural syntax to invoke this command.
Absence of Workaround
Direct manual patching via
db applyis entirely blocked. The utility expects an undocumented,jq-like expression format (where the parser enforces tokens likedef/if/(/[/../{/-/.).Neither a broad full-document replacement nor a hyper-targeted JSON-pointer operation will validate against the internal structural model, consistently resulting in schema rejection messages:
As it stands, end users hosting on a NAT'd cloud VPS have zero supported paths to manually or programmatically set
wanIp.Expected Behavior
Proposed Solutions & Fixes
1. Fix CLI Argument Inheritance for
set-wanThe
set-wancommand must correctly inherit the<SUBNET>positional argument from its parent context without requiring a second, duplicate positional argument at the tail.subnet <SUBNET> set-wan --wan-ip <IP><SUBNET>parameter and successfully update the subnet's WAN IP.2. Backfill
wanIpvia MigrationThe database upgrade migration routine must be updated to prevent existing installations from entering an unusable state.
wanIpfrom the active network interface.wanIpusing the embedded IP addresses found inside legacyport-forwardentries.3. Implement Fallback Resolution for Port Forwarding
Both the CLI
port-forward addcommand and the Web UI Add published port dialog must support NAT'd VPS setups.wanIpstate field evaluates tonull, the application must queryget-available-ipsto dynamically resolve it.Steps to Reproduce
Steps to Reproduce
1. Confirm Environment and Available Interfaces
Run StartTunnel 1.2.1 on a Debian 13 VPS whose public IPv4 is NAT'd and not present on the NIC (only a private IP on the interface).
2. Attempt to Add Port Forward via CLI
Try to add a port forward using the command-line interface.
$ sudo start-tunnel port-forward add --label "LND" 9735 10.59.203.3:9735Verbatim Error:
3. Attempt to Add Port Forward via Web UI
Navigate to Port Forwards → Add published port and enter the details:
Verbatim Error:
4. Attempt to Set Subnet WAN IP (Both Forms Fail)
Try to manually set the subnet WAN IP so the forward can resolve. Both syntax forms fail to invoke properly.
Form A (Missing argument error):
Verbatim Error:
Form B (Duplicate key error):
Verbatim Error:
Anything else?
System Diagnostics & Impact Assessment
📋 Full Environment Profile
{"status":"up-to-date","installed":"1.2.1","candidate":"1.2.1"}curl -sSL https://start9.com/start-tunnel/install.sh | shens3bound to private IP172.16.0.12/20). Matches standard documentation models for AWS EC2, Oracle Cloud, GCP, and Azure.10.59.203.1/24) containing one StartOS server device (10.59.203.3) and three downstream clients.🗄️ Database Evidence (
db dumpAnalysis)A redacted look at the post-migration database state shows exactly where state validation collapses. Existing entries remain functional due to inline legacy keys, while the new
wanIpparent tracking keys remain explicitly empty:{ "gateways": { "ens3": { "ipInfo": { "wanIp": null } } }, "wg": { "subnets": { "10.59.203.1/24": { "clients": { "10.59.203.3": { "kind": "server", "allowAutoPortForward": true, "wanIp": null } // All other sub-connected clients are similarly set to "wanIp": null }, "wanIp": null // <-- CRITICAL BLOCK: Gating condition for all new port-forward adds } } }, "portForwards": { // Grandfathered entries carry the external IP inline; DNAT mechanics process normally "172.16.0.12:443": { "target": "10.59.203.2:443", "kind": "dnat", "enabled": true }, "172.16.0.12:8333": { "target": "10.59.203.3:8333", "kind": "dnat", "enabled": false } } }💥 Severity & Scope of Impact
Port forwarding configuration is fundamentally broken across all virtual private servers operating behind an edge NAT layout (including AWS, Azure, GCP, and Oracle Cloud).
Because pre-existing DNAT rules continue to pass traffic perfectly, the underlying translation layer remains healthy. The failure is strictly administrative: the software blocks new additions when
wanIpis null, yet provides no valid command sequence to populate it.🛠️ Recommended Code Fixes
<SUBNET>positional argument requirement from theset-wancommand structure. Allow it to natively inherit context from the parentsubnetcommand space.set-dnsandset-ipv6) to ensure this duplicate positional parameter defect is not replicated across other network configuration modules.wanIpdata property using either the active interface IP or values parsed from legacy pre-upgrade port-forward records.port-forward addsequence. IfwanIpresolves to null, fallback to queryget-available-ipsdynamically instead of executing an immediate hard failure.