{"record":{"id":"b6bc2756e09a2e60","repo":"NationalSecurityAgency/ghidra","slug":"address-must-be-port-or-host-port","errorCode":null,"errorMessage":"address must be 'port' or 'host:port'","messagePattern":"address must be 'port' or 'host:port'","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py","lineNumber":205,"sourceCode":"\ndef ghidra_trace_listen(address: str = '127.0.0.1:0') -> None:\n    \"\"\"Listen for Ghidra to connect for tracing.\n\n    Takes an optional address for the host and port on which to listen.\n    Either the form 'host:port' or just 'port'. If omitted, it will bind\n    to an ephemeral port on localhost. If only the port is given, it will\n    bind to that port on localhost. This command will block until the\n    connection is established.\n    \"\"\"\n\n    STATE.require_no_client()\n    parts = address.split(':')\n    if len(parts) == 1:\n        host, port = '127.0.0.1', parts[0]\n    elif len(parts) == 2:\n        host, port = parts\n    else:\n        raise RuntimeError(\"address must be 'port' or 'host:port'\")\n\n    try:\n        s = socket.socket()\n        s.bind((host, int(port)))\n        host, port = s.getsockname()\n        s.listen(1)\n        print(\"Listening at {}:{}...\".format(host, port))\n        c, (chost, cport) = s.accept()\n        s.close()\n        print(\"Connection from {}:{}\".format(chost, cport))\n        STATE.client = Client(c, \"dbgeng.dll\", methods.REGISTRY)\n    except ValueError:\n        raise RuntimeError(\"port must be numeric\")\n\n\ndef ghidra_trace_disconnect() -> None:\n    \"\"\"Disconnect Python from Ghidra for tracing.\"\"\"\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py#L187-L223","documentation":"Raised by ghidra_trace_listen() (commands.py:199-205) when the address splits into other than 1 or 2 parts. Unlike connect, listen accepts either a bare 'port' (bound on 127.0.0.1) or 'host:port', but rejects addresses with two or more colons (IPv6 literals) or empty/whitespace inputs that produce unexpected counts.","triggerScenarios":"Passing an IPv6 literal like '[::1]:12345' (3 parts); passing 'a:b:c'; passing an empty string with an unexpected number of colons; passing a value with leading/trailing colons.","commonSituations":"IPv6 listening address where the bracket form was not stripped; misformatted config; copy/paste including a scheme prefix.","solutions":["Pass either 'port' or 'host:port' with a single colon, e.g. '12345' or '0.0.0.0:12345'.","For IPv6, fall back to a hostname or IPv4 binding.","Trim whitespace and strip any scheme/brackets before calling."],"exampleFix":"// before\nghidra_trace_listen('[::1]:12345')   # 3 parts after split\n\n// after\nghidra_trace_listen('12345')           # binds 127.0.0.1:12345","handlingStrategy":"validation","validationCode":"def validate_listen_address(address):\n    parts = address.split(':')\n    if len(parts) not in (1, 2):\n        raise ValueError(\"address must be 'port' or 'host:port'\")\n    return parts\n\nvalidate_listen_address(address)\nghidra_trace_listen(address)","typeGuard":"def is_listen_address(address) -> bool:\n    if not isinstance(address, str):\n        return False\n    return len(address.split(':')) in (1, 2)","tryCatchPattern":"try:\n    ghidra_trace_listen(address)\nexcept RuntimeError as e:\n    if \"must be 'port' or 'host:port'\" in str(e):\n        raise ValueError('reformat the listen address') from e\n    raise","preventionTips":["Avoid IPv6 literals; use IPv4 or hostname.","Trim whitespace and brackets before calling.","Prefer the bare-port form for localhost binds."],"tags":["usage","connection","validation","ghidra"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}