{"record":{"id":"67e15f0f82c5fad1","repo":"sgl-project/sglang","slug":"len-extents-extents-exceed-bumparena-max-extent","errorCode":null,"errorMessage":"{len(extents)} extents exceed BUMPARENA_MAX_EXTENTS ({BumpArenaStub.MAX_EXTENTS})","messagePattern":"(.+?) extents exceed BUMPARENA_MAX_EXTENTS \\((.+?)\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/utils/cuda_vmm_utils.py","lineNumber":477,"sourceCode":"            ctypes.c_size_t,\n        ]\n        self._fn_set_extents.restype = None\n        self._fn_set_align = lib[f\"bumparena_set_align_{self.sfx}\"]\n        self._fn_set_align.argtypes = [ctypes.c_size_t]\n        self._fn_set_align.restype = None\n        self._fn_cursor = lib[f\"bumparena_cursor_{self.sfx}\"]\n        self._fn_cursor.argtypes = []\n        self._fn_cursor.restype = ctypes.c_size_t\n        self._fn_freed = lib[f\"bumparena_freed_{self.sfx}\"]\n        self._fn_freed.argtypes = []\n        self._fn_freed.restype = ctypes.c_size_t\n        return lib\n\n    def set_extents(self, extents: List[tuple]) -> None:\n        \"\"\"Register ``(base, nbytes)`` extents (first-fit order) and reset\n        every bump cursor.\"\"\"\n        if len(extents) > BumpArenaStub.MAX_EXTENTS:\n            raise ValueError(\n                f\"{len(extents)} extents exceed BUMPARENA_MAX_EXTENTS \"\n                f\"({BumpArenaStub.MAX_EXTENTS})\"\n            )\n        n = len(extents)\n        bases = (ctypes.c_void_p * n)(*(base for base, _ in extents))\n        sizes = (ctypes.c_size_t * n)(*(nbytes for _, nbytes in extents))\n        self._fn_set_extents(bases, sizes, ctypes.c_size_t(n))\n\n    def set_align(self, nbytes: int) -> None:\n        self._fn_set_align(ctypes.c_size_t(nbytes))\n\n    @property\n    def cursor_bytes(self) -> int:\n        return int(self._fn_cursor())\n\n    @property\n    def freed_bytes(self) -> int:\n        \"\"\"Bytes handed back through ``free`` since the last ``set_extents``","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/utils/cuda_vmm_utils.py#L459-L495","documentation":"BumpArenaStub.set_extents raises this when the number of (base, nbytes) extents passed in exceeds BumpArenaStub.MAX_EXTENTS, a fixed capacity limit for the bump-arena's extent array. The stub keeps a bounded ctypes array of extents for first-fit allocation, so more extents than MAX_EXTENTS cannot be registered.","triggerScenarios":"Calling set_extents (directly or via __init__ / borrow_graph_pool) with a list of extents longer than BumpArenaStub.MAX_EXTENTS (controlled by the BUMPARENA_MAX_EXTENTS constant).","commonSituations":"Fragmented allocations (many small memaps/graph pool segments) after a change in graph capture batch sizes, mem-fraction, or TP size; or overriding BUMPARENA_MAX_EXTENTS to a smaller value than the workload produces.","solutions":["Reduce the number of extents by coalescing contiguous/adjacent reservations into fewer larger extents before calling set_extents.","Increase BUMPARENA_MAX_EXTENTS (env/config) if the workload legitimately needs more segments.","Check for memory fragmentation sources (many small cudaMalloc / graph pool re-borrows) and consolidate pool allocations."],"exampleFix":"// before\narena.set_extents([(b, s) for b, s in raw_extents])\n\n// after\nraw_extents.sort()\nmerged = []\nfor base, size in raw_extents:\n    if merged and merged[-1][0] + merged[-1][1] == base:\n        merged[-1] = (merged[-1][0], merged[-1][1] + size)\n    else:\n        merged.append((base, size))\narena.set_extents(merged)","handlingStrategy":"validation","validationCode":"from python.sglang.srt.utils.cuda_vmm_utils import BumpArenaStub\nmerged = coalesce_contiguous(extents)\nassert len(merged) <= BumpArenaStub.MAX_EXTENTS, f\"{len(merged)} > {BumpArenaStub.MAX_EXTENTS}; raise BUMPARENA_MAX_EXTENTS\"","typeGuard":null,"tryCatchPattern":"try:\n    arena.set_extents(extents)\nexcept ValueError as e:\n    if \"BUMPARENA_MAX_EXTENTS\" in str(e):\n        arena.set_extents(coalesce_contiguous(extents))\n    else:\n        raise","preventionTips":["Coalesce contiguous extents before registering","Size BUMPARENA_MAX_EXTENTS to worst-case segment count for your graph-capture config"],"tags":["cuda","vmm","memory","capacity-limit"],"backgroundTag":"capacity-limit-exceeded","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}