NationalSecurityAgency/ghidra · error · RuntimeError

ADDRESS must be PORT or HOST:PORT

Error message

ADDRESS must be PORT or HOST:PORT

What it means

`ghidra trace listen` accepts 0 or 1 address argument. With one argument it splits on `:`: exactly 1 part means port-only (host defaults to 127.0.0.1), exactly 2 means HOST:PORT, and anything else (3+ parts) raises this. So a raw IPv6 listen address triggers it.

Source

Thrown at Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py:325

    to an ephemeral port on localhost. If only the port is given, it will
    bind to that port on localhost. This command will block until the
    connection is established.
    """

    args = shlex.split(command)
    host: str
    port: Union[str, int]
    if len(args) == 0:
        host, port = '127.0.0.1', 0
    elif len(args) == 1:
        address = args[0]
        parts = address.split(':')
        if len(parts) == 1:
            host, port = '127.0.0.1', parts[0]
        elif len(parts) == 2:
            host, port = parts
        else:
            raise RuntimeError("ADDRESS must be PORT or HOST:PORT")
    else:
        raise RuntimeError("Usage: ghidra trace listen [ADDRESS]")

    STATE.require_no_client()
    try:
        s = socket.socket()
        s.bind((host, int(port)))
        host, port = s.getsockname()
        s.listen(1)
        print(f"Listening at {host}:{port}...")
        c, (chost, cport) = s.accept()
        s.close()
        print(f"Connection from {chost}:{cport}")
        STATE.client = Client(
            c, util.LLDB_VERSION.display, methods.REGISTRY)
    except ValueError:
        raise RuntimeError("PORT must be numeric")

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Use a plain PORT (`ghidra trace listen 8080`) or HOST:PORT (`ghidra trace listen 0.0.0.0:8080`)
  2. Avoid raw IPv6 literals on this path; bind an IPv4 address or omit the host

Example fix

// before
ghidra trace listen ::1:8080
// after
ghidra trace listen 127.0.0.1:8080
Defensive patterns

Strategy: validation

Validate before calling

def valid_listen_addr(token: str) -> bool:
    parts = token.split(':')
    return len(parts) in (1, 2)

Type guard

from typing import Union, Tuple
def parse_listen_addr(token: str) -> Union[Tuple[str, str], None]:
    parts = token.split(':')
    if len(parts) == 1:
        return '127.0.0.1', parts[0]
    if len(parts) == 2:
        return parts[0], parts[1]
    return None

Try / catch

try:
    ghidra_trace_listen(debugger, token, result, internal_dict)
except RuntimeError as e:
    if str(e) == 'ADDRESS must be PORT or HOST:PORT':
        # reduce to PORT or HOST:PORT (drop IPv6 / extra colons)
        ...
    raise

Prevention

When it happens

Trigger: `ghidra trace listen ::1:8080`; `ghidra trace listen a:b:c`; any address token containing two or more colons.

Common situations: Trying to bind an IPv6 address directly; a mistyped address with extra colons.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/796e726505c7430e. Report an issue: GitHub.