NationalSecurityAgency/ghidra · error · RuntimeError

address must be in the form 'host:port'

Error message

address must be in the form 'host:port'

What it means

Raised by ghidra_trace_connect (commands.py:171-173) when address.split(':') does not yield exactly two parts. Unlike ghidra_trace_listen, connect requires the strict two-part host:port form; a bare port or an address with two or more colons is rejected.

Source

Thrown at Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py:173


STATE = State()


def ghidra_trace_connect(address: Optional[str] = None) -> None:
    """Connect Python to Ghidra for tracing.

    Address must be of the form 'host:port'
    """

    STATE.require_no_client()
    if address is None:
        raise RuntimeError(
            "'ghidra_trace_connect': missing required argument 'address'")

    parts = address.split(':')
    if len(parts) != 2:
        raise RuntimeError("address must be in the form 'host:port'")
    host, port = parts
    try:
        c = socket.socket()
        c.connect((host, int(port)))
        # TODO: Can we get version info from the DLL?
        STATE.client = Client(c, "x64dbg", methods.REGISTRY)
        print(f"Connected to {STATE.client.description} at {address}")
    except ValueError:
        raise RuntimeError("port must be numeric")


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

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Provide exactly one colon separating host and port, e.g. '127.0.0.1:12345'.
  2. For a port-only input, prepend the host: ghidra_trace_connect(f'127.0.0.1:{port}').
  3. For IPv6, supply an explicit host that splits to exactly two tokens or normalize before calling.

Example fix

// before
ghidra_trace_connect('8080')

// after
ghidra_trace_connect('127.0.0.1:8080')
Defensive patterns

Strategy: validation

Validate before calling

def normalize_connect_address(s: str) -> str:
    parts = s.split(':')
    if len(parts) == 1:
        return f'127.0.0.1:{parts[0]}'
    if len(parts) != 2:
        raise ValueError(f"address must be host:port, got {s!r}")
    return s

ghidra_trace_connect(normalize_connect_address(raw))

Type guard

def is_host_port(s: str) -> bool:
    return isinstance(s, str) and len(s.split(':')) == 2

Try / catch

try:
    ghidra_trace_connect(address)
except RuntimeError as e:
    if 'form' in str(e):
        address = f'127.0.0.1:{address}'
        ghidra_trace_connect(address)
    else:
        raise

Prevention

When it happens

Trigger: Calling ghidra_trace_connect('8080') (port only, 1 part), ghidra_trace_connect('localhost') (1 part), ghidra_trace_connect('a:b:c') (3 parts), or an IPv6-style address with multiple colons.

Common situations: User copies a port-only value intended for listen into connect; passing an IPv6 literal (e.g. '[::1]:8080' splits to more than 2 on a naive split); trailing/leading colons producing empty parts.

Related errors


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