Home / Alt manpages / gh-codespace-ports-forward(1)

  • gh-codespace-ports-forward(1)
  • User command
  • linux

Forward a Codespace Port with gh codespace ports forward

gh codespace ports forward connects a service running inside a GitHub Codespace to a port on your Linux machine. Allow about ten minutes if the Codespace is already running and the application is ready to listen. The examples use the installed GitHub CLI 2.87.3, released 23 February 2026.

The installed command's manual is unusually short: the syntax is gh codespace ports forward <remote-port>:<local-port>..., plus the codespace-selection flags it inherits from the parent command. The current upstream manual documents the same syntax and a newer --all-interfaces option, so check your local help rather than copying flags between versions.

1. Check the installed command and your login

Run these as your ordinary user. Port forwarding does not need sudo, and adding it can pull in a different set of credentials and configuration from the ones gh actually uses:

$ gh version
gh version 2.87.3 (2026-02-23)
https://github.com/cli/cli/releases/tag/v2.87.3
$ gh codespace ports forward --help
Forward ports

USAGE
  gh codespace ports forward <remote-port>:<local-port>... [flags]

Confirm the help output on your machine includes the command you intend to use. If you have not authenticated, run gh auth login and complete its prompts, then check the resulting account with gh auth status. Do not paste that diagnostic output into a public issue if it contains host or account details.

Checkpoint

You have a working gh executable, an authenticated account with access to the Codespace, and a version recorded for later troubleshooting.

2. Identify the Codespace and the service port

In the mapping, the first number is the port inside the Codespace and the second is the unused port on your machine. The application must already be listening on the remote port: for example, something on remote port 8000 can be exposed locally as port 18000.

$ gh codespace list
$ gh codespace ports -c CODESPACE_NAME

Swap in the exact name from the list command. The port listing shows the source port, visibility and browser URL for anything Codespaces already knows about. If your service is missing, start it inside the Codespace first and list again: a free local port proves nothing about the health of the remote application.

Use a non-privileged local port above 1024 unless you have a specific reason to bind lower, and check the candidate is free before you commit to it:

$ ss -ltn | grep -E ':18000\b' || echo 'local port 18000 is free'
local port 18000 is free

3. Forward one port to loopback

On the installed 2.87.3 command, run:

$ gh codespace ports forward 8000:18000 -c CODESPACE_NAME

Keep this terminal open: the forwarding stays active only while the process runs. It may print connection information or simply sit attached to the terminal, and either is normal for a long-running tunnel.

From a second terminal, inspect the listener while the first command keeps running:

$ ss -ltn | grep -E ':(18000)\b'
LISTEN 0      128        127.0.0.1:18000      0.0.0.0:*

Spacing and queue size will vary. The property that matters is the local address: 127.0.0.1:18000, or the IPv6 loopback address [::1]:18000, limits access to this machine. Open the service at http://127.0.0.1:18000/ if it speaks HTTP, or use whatever client fits it.

4. Treat an old gh version as a network exposure

This local 2.87.3 release predates GitHub CLI's fix for a port-forwarding issue. The GitHub advisory lists versions 2.28.0 through 2.97.x as affected, and says 2.98.0 changes the default listener to loopback. On an affected version, the ordinary forward command can bind a wildcard address such as 0.0.0.0:18000, making the service reachable from network interfaces other than loopback for as long as the command runs.

Security warning

Before forwarding a real service on 2.87.3, upgrade gh through your normal package manager, then rerun gh version and gh codespace ports forward --help. This guide will not install or upgrade packages for you. If upgrading is not possible, treat any forward as a temporary exposure: use a trusted network, pick a harmless test service, watch ss -ltn, and stop the moment the listener is not loopback-only.

The current CLI documents --all-interfaces as an explicit opt-in for listening on every interface. It is not present in the installed 2.87.3 help, so do not add it here and do not assume an old version already defaults the newer way.

5. Stop forwarding and recover from common failures

Return to the terminal running the forwarder and press Control-C, then check the local listener is gone:

$ ss -ltn | grep -E ':(18000)\b' || echo 'forwarding stopped'
forwarding stopped

This only stops the local tunnel: the application inside the Codespace keeps running and the Codespace itself is untouched. Run the same command again whenever you need another session.

  • gh cannot select or access the Codespace. Supply -c CODESPACE_NAME explicitly and check gh auth status.
  • Local bind fails with address-in-use. Pick another local port such as 18001 and repeat the free-port check.
  • Remote connection fails. Confirm the application is still running inside the Codespace and that 8000 is really its listening port. Never kill an unrelated process to free things up unless you have identified it and have a recovery plan.

A Codespace port's GitHub visibility is a separate setting from the local listener. Private, organisation and public visibility control access through the Codespaces service; none of them make a wildcard-bound local listener safe. Keep the port private unless sharing is deliberate, and check it with gh codespace ports after the tunnel is stopped or restarted.

Done means

  • Recorded the local version. Checked gh's own help output too.
  • Selected the exact Codespace. And confirmed the remote application port.
  • Checked the local port was free. Before forwarding anything to it.
  • Confirmed a loopback-only listener. With ss -ltn, or stopped because an old version exposed every interface.
  • Stopped the tunnel deliberately. With Control-C, and verified the local listener disappeared.