NationalSecurityAgency/ghidra · error · RuntimeError

address must be 'port' or 'host:port'

Error message

address must be 'port' or 'host:port'

What it means

Thrown by ghidra_trace_listen in the drgn agent when the address string, after splitting on ':', does not yield exactly 1 or 2 parts. A valid address is either a bare port ('12345') or 'host:port'. Three or more colons (or a leading/trailing colon producing an empty part in some cases) trigger this RuntimeError.

Source

Thrown at Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/commands.py:191

def ghidra_trace_listen(address: str = '127.0.0.1:0') -> None:
    """
    Listen for Ghidra to connect for tracing

    Takes an optional address for the host and port on which to listen.
    Either the form 'host:port' or just 'port'. If omitted, it will bind
    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.
    """

    STATE.require_no_client()
    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'")

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


def ghidra_trace_disconnect() -> None:
    """Disconnect Python from Ghidra for tracing"""

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Use the form 'port' (e.g. '12345') or 'host:port' (e.g. '127.0.0.1:12345') only.
  2. For IPv6 localhost use the bracket-free numeric form '0:12345' is NOT valid — use '127.0.0.1:12345' since this parser does not support IPv6.
  3. Check the address string does not contain more than one colon.

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 validate_listen_address(address: str) -> None:
    parts = address.split(':')
    if len(parts) not in (1, 2):
        raise ValueError(
            f"Address must be 'port' or 'host:port', got {len(parts)} parts: {address}")

# Call before ghidra_trace_listen:
validate_listen_address(address)

Try / catch

try:
    ghidra_trace_listen(address)
except RuntimeError as e:
    if 'address must be' in str(e):
        print(f"Invalid listen address '{address}'. Use 'port' or 'host:port' only.")
    else:
        raise

Prevention

When it happens

Trigger: Calling ghidra_trace_listen('::8080') (two colons, three parts), ghidra_trace_listen('a:b:c'), ghidra_trace_listen('host:port:extra'), or an address containing an IPv6-style address like '[::1]:8080' which splits into more than 2 parts on ':'.

Common situations: Passing an IPv6 address (which contains colons) without bracket notation; accidentally appending a path or extra segment to the address; empty address string that splits to [''] (1 part, but then port parse fails elsewhere); double separator '::' from a malformed config.

Related errors


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