{"record":{"id":"6bd785d59f3bd10e","repo":"NationalSecurityAgency/ghidra","slug":"address-must-be-port-or-host-port-6bd785","errorCode":null,"errorMessage":"address must be 'port' or 'host:port'","messagePattern":"address must be 'port' or 'host:port'","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py","lineNumber":202,"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, \"x64dbg\", 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":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py#L184-L220","documentation":"Raised by ghidra_trace_listen (commands.py:196-202) when address.split(':') yields neither 1 nor 2 parts. listen is more permissive than connect (a bare port maps to 127.0.0.1), but three or more colon-separated tokens are rejected.","triggerScenarios":"Calling ghidra_trace_listen('a:b:c') (3 parts), an empty string (split gives [''], which is 1 part and would NOT trigger this), or any address with 2+ colons. Note: 1 or 2 parts are accepted.","commonSituations":"Passing an IPv6 address with multiple colons; a copy/paste that concatenated host:port:extra; a default-argument override that introduced extra colons.","solutions":["Use a bare port ('12345') or host:port ('127.0.0.1:12345') only.","Normalize IPv6 or multi-colon input to a two-token host:port before calling.","If forwarding user input, reject values where address.split(':') length is > 2 upstream."],"exampleFix":"// before\nghidra_trace_listen('host:port:extra')\n\n// after\nghidra_trace_listen('12345')","handlingStrategy":"validation","validationCode":"def normalize_listen_address(s: str) -> str:\n    parts = s.split(':')\n    if len(parts) > 2:\n        raise ValueError(f\"listen address must be 'port' or 'host:port', got {s!r}\")\n    return s\n\nghidra_trace_listen(normalize_listen_address(raw))","typeGuard":"def is_listen_address(s: str) -> bool:\n    return isinstance(s, str) and len(s.split(':')) <= 2","tryCatchPattern":"try:\n    ghidra_trace_listen(address)\nexcept RuntimeError as e:\n    if \"'port' or 'host:port'\" in str(e):\n        # fall back to port-only on localhost\n        port = address.split(':')[-1]\n        ghidra_trace_listen(port)\n    else:\n        raise","preventionTips":["Limit listen input to a single port or a single host:port.","Reject multi-colon input upstream for IPv6 until normalized.","Default the field to a bare port to steer users to the safe form."],"tags":["listen","argument-validation","address-parsing","python"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}