Verify the local backend before the public URL
When a Funnel URL times out or returns a gateway error, opening an external firewall first can hide a local application failure. Funnel is the layer that publishes a local service. The first boundary is whether the backend answers the same target on the Funnel node. Rebuilding Funnel configuration cannot repair a stopped backend.
Also separate Serve from Funnel. Serve shares a service within the tailnet; Funnel publishes it to the internet. Without recording both states, an endpoint that works internally but is closed publicly can be mistaken for a backend problem.
Five boundaries between an external request and the backend
| Boundary | Evidence | Failure means |
|---|---|---|
| Local service | Target response and listen address | The problem exists before Funnel. |
| Tailscale node | Login state and client version | The node may not receive control-plane configuration. |
| Funnel configuration | Target and public URL shown by status | Old Serve or Funnel state may remain. |
| Tailnet requirements | MagicDNS, HTTPS, and funnel node attribute | A public requirement is missing. |
| Public listener | One of 443, 8443, or 10000 | The requested external port is unsupported. |
tailscale version
tailscale status
tailscale serve status
tailscale funnel status
curl -sS -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1:3000/health
Replace the final path with the real backend health endpoint. If 127.0.0.1:3000 does not answer, repair the service process, container port, or listen address first. Funnel does not require exposing the backend to the entire LAN.
Compare tailnet configuration with Funnel requirements
Tailscale documents Funnel requirements as Tailscale 1.38.3 or later, MagicDNS, tailnet HTTPS, and a funnel node attribute. Funnel uses only names in the tailnet *.ts.net domain and requires TLS. Public listeners are limited to 443, 8443, and 10000.
When an old command was copied from a previous installation, account for Serve and Funnel CLI changes around client 1.52. Use the help text from the installed client and the current CLI reference to rebuild the target.
The next three commands are read-only. Status can expose public URLs and internal targets; do not paste the complete output into public logs.
tailscale funnel --help
tailscale serve status
tailscale funnel status
Use the following mutation only when internet publication is intended, the backend authentication and data scope are acceptable, and the existing port-443 listener has been checked for conflicts. Privately record the existing Serve/Funnel URLs, targets, and options first. --bg permits status to run next in the same terminal, but publication can persist after the command ends or you log out; manage it until explicitly disabled.
tailscale funnel --bg --https=443 http://127.0.0.1:3000
tailscale funnel statusWithout --bg, the foreground command occupies the terminal. Query status in another terminal; Ctrl+C ends that foreground invocation. The help text on a development host running Tailscale 1.102.4 confirmed --bg and its false default. Internet publication itself was not tested.
Use the symptom to choose the next branch
- Local curl also fails: leave Funnel unchanged and repair the backend service or container.
- Local access works but Funnel status is empty: the configuration may not have been saved, or only Serve may be enabled. Inspect the command and its permission prompt result.
- Status exists on an unsupported public port: move the listener to a supported port. Keep the backend port distinct; the local service can use another port.
- It works inside the tailnet but not from the internet: recheck Serve versus Funnel state, the funnel node attribute, and HTTPS. Do not assume that changing a general ACL alone fixes public exposure.
- It is intermittently slow or disconnected: Funnel has non-configurable bandwidth limits. Record backend latency and the Tailscale path, but do not invent a numeric limit that the documentation does not publish.
Verification and rollback
After repair, test the backend locally on the node, then test the public URL from outside the tailnet. A Tailscale-connected device on the same Wi-Fi may not exercise the internet publication path. Preserve response headers and times so local and public results can be compared.
If the newly enabled HTTPS port-443 listener publishes the wrong target, disable that listener with tailscale funnel --https=443 off when supported by the installed CLI, then inspect status. If you modified an existing listener, restore its recorded target and options; off alone is not rollback. Reset clears the complete Funnel configuration and belongs only to a deliberate decision to stop all publication after checking the impact. Status need not be entirely empty when other listeners remain.
Related guides
Official references
- Tailscale Funnel – required version, MagicDNS, HTTPS, node attribute, and public-port limits
- tailscale funnel CLI – status, reset, HTTPS listener, and target syntax
- Tailscale Serve – scope difference between tailnet-only Serve and internet Funnel
- Tailscale connectivity troubleshooting – basic node and path isolation
Earlier verification notes preserved from this article
Verification level: official documentation checked
Funnel requirements and current CLI scope were checked against Tailscale documentation. No specific tailnet public path was reproduced, so the guide does not assert a bandwidth or relay-path root cause.