{"record":{"id":"a58138b69d3b92d8","repo":"sgl-project/sglang","slug":"invalid-endpoint-must-contain-inproc-or-tcp","errorCode":null,"errorMessage":"Invalid endpoint: must contain 'inproc' or 'tcp'","messagePattern":"Invalid endpoint: must contain 'inproc' or 'tcp'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/disaggregation/kv_events.py","lineNumber":591,"sourceCode":"            The endpoint with the port offset by data_parallel_rank\n                or suffix appended\n        \"\"\"\n        # Do nothing if input is None or data_parallel_rank is 0\n        if not endpoint or data_parallel_rank == 0:\n            return endpoint\n\n        if \"inproc\" in endpoint:\n            return f\"{endpoint}_dp{data_parallel_rank}\"\n        if \"tcp\" in endpoint:\n            if endpoint and \":\" in endpoint:\n                # Get everything after the last colon (the port)\n                last_colon_idx = endpoint.rfind(\":\")\n                base_addr = endpoint[:last_colon_idx]\n                base_port = int(endpoint[last_colon_idx + 1 :])\n                new_port = base_port + data_parallel_rank\n                return f\"{base_addr}:{new_port}\"\n            return endpoint\n        raise ValueError(\"Invalid endpoint: must contain 'inproc' or 'tcp'\")\n\n\nclass KVEventsConfig(BaseModel):\n    \"\"\"Configuration for KV event publishing.\"\"\"\n\n    publisher: str = \"null\"\n    \"\"\"The publisher to use for publishing kv events. Can be \"null\", \"zmq\".\n    \"\"\"\n\n    endpoint: str = \"tcp://*:5557\"\n    \"\"\"The zmq endpoint to use for publishing kv events.\n    \"\"\"\n\n    replay_endpoint: Optional[str] = None\n    \"\"\"The zmq endpoint to use for replaying kv events.\n    \"\"\"\n\n    buffer_steps: int = 10_000","sourceCodeStart":573,"sourceCodeEnd":609,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/disaggregation/kv_events.py#L573-L609","documentation":"offset_endpoint_port only knows how to offset ports for 'inproc' and 'tcp' ZMQ endpoints; any other transport string falls through to a ValueError. It offsets the port by the attention data-parallel rank so replicas bind sequential ports.","triggerScenarios":"Calling KVEventsConfig publishers (e.g. Kafka/Radix publisher) whose endpoint string is not a zmq tcp:// or inproc:// address, with data_parallel_rank > 0, or passing endpoint without a parseable host:port.","commonSituations":"Setting a kafka bootstrap server like 'kafka:9092' as the ZMQ endpoint, or a custom transport added without extending this helper.","solutions":["Use a tcp://host:port (or inproc://...) endpoint for ZMQ-based publishers","Extend the helper for your transport if you genuinely need non-tcp endpoints","Ensure the endpoint contains a colon-separated trailing port so the offset arithmetic works"],"exampleFix":"// before\nendpoint = \"kafka-broker:9092\"\n# after\nendpoint = \"tcp://127.0.0.1:55557\"","handlingStrategy":"validation","validationCode":"scheme = endpoint.split(\"://\", 1)[0] if \"://\" in endpoint else endpoint.split(\":\", 1)[0]\nassert scheme in (\"tcp\", \"inproc\"), f\"unsupported zmq endpoint scheme: {endpoint}\"","typeGuard":"def is_offsettable_endpoint(ep: str) -> bool:\n    return \"tcp\" in ep or \"inproc\" in ep and ep.rfind(\":\") != -1","tryCatchPattern":"catch ValueError from offset_endpoint_port at startup and fail fast with the offending endpoint in the message","preventionTips":["Validate kv-events endpoints in config parsing before launch","Document that only zmq tcp/inproc endpoints are offsettable"],"tags":["kv-events","zmq","endpoint","config"],"backgroundTag":"invalid-endpoint-url","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}