#405·portless

`portless alias` cannot scope a route to one TLD when multiple are configured

Author: williamdentonCreated Sep 3, 2026Updated Sep 3, 2026

Summary

When the proxy serves more than one TLD, portless alias <name> <port> always registers the name under every served TLD. There is no way to register a route under one of them.

This is fine when the argument is a bare name, which is the documented case. It breaks down when the argument is already a fully-qualified hostname that is only meaningful under one TLD: parseHostnames strips the matching TLD suffix back to the bare label and re-appends all the others.

Environment

  • portless 0.15.5
  • macOS / Darwin, Node 26.7.0
  • Installed service mode, multiple --tld values

Repro

bash
export PORTLESS_STATE_DIR=/tmp/portless-repro
mkdir -p "$PORTLESS_STATE_DIR"
printf 'dev.example.com\nlocal.example.com\n' > "$PORTLESS_STATE_DIR/proxy.tlds"

portless alias api.dev.example.com 8443

Actual

Alias registered: api.dev.example.com, api.local.example.com -> 127.0.0.1:8443

api.local.example.com was never asked for, and it is now claimed by whatever is on :8443.

Passing --tld does not help — handleAlias only inspects --help, --remove and --force, so any other flag is silently ignored and the command reports success:

bash
$ portless alias api.dev.example.com 8443 --tld dev.example.com --force
Alias registered: api.dev.example.com, api.local.example.com -> 127.0.0.1:8443

--remove has the mirror-image problem, so there is also no way to drop just one of the hostnames:

bash
$ portless alias --remove api.dev.example.com
Removed alias: api.dev.example.com, api.local.example.com

Expected

A way to say which TLD the route belongs to, with the current fan-out staying the default:

Alias registered: api.dev.example.com -> 127.0.0.1:8443

Multi-TLD (#344) makes it reasonable to serve one TLD per class of service — an internal-parity domain for services tunnelled to a deployed environment, and a separate domain for things running locally. Today the two cannot coexist, because a route registered under one name claims that name under the other domain as well, where a different service is entitled to it.

Proposed change

Accept a repeatable --tld on portless alias, validated against what the proxy actually serves, applying to both registration and --remove. Additive: omit it and behaviour is unchanged.

Workaround

Registering the single route directly through the exported RouteStore, which is the same store handleAlias writes through, lock included.