pypa/pip · warning · TooManyTagsError
Compressed tag set would generate {tag_count} tags, exceedin
Error message
Compressed tag set would generate {tag_count} tags, exceeding limit {limit} What it means
Raised as TooManyTagsError (ValueError subclass) by parse_tag (tags.py:292-296) when limit is not None and the product of the sizes of all components (interpreters x abis x platforms) exceeds limit. This is a DoS-guard preventing a single compressed tag string from exploding into an enormous tag set (e.g. a tag with many alternatives in each field).
Source
Thrown at src/pip/_vendor/packaging/tags.py:293
raise ValueError("limit must be non-negative")
component_parts = [component.split(".") for component in tag.split("-")]
for parts in component_parts:
if "" in parts:
component = ".".join(parts)
raise InvalidTag(f"Tag {tag!r} has an empty component: {component!r}")
if validate_order and parts != sorted(parts):
component = ".".join(parts)
raise UnsortedTagsError(
f"Tag component {component!r} is not in sorted order per PEP 425"
)
tag_count = 1
for parts in component_parts:
tag_count *= len(parts)
if limit is not None and tag_count > limit:
raise TooManyTagsError(
f"Compressed tag set would generate {tag_count} tags, exceeding "
f"limit {limit}"
)
try:
interpreters, abis, platforms = component_parts
except ValueError as exc:
raise InvalidTag(f"Tag {tag!r} must have exactly three components") from exc
for interpreter in interpreters:
if not interpreter.isidentifier():
raise InvalidTag(f"Tag {tag!r} has an invalid interpreter: {interpreter!r}")
return frozenset(
Tag(interpreter, abi, platform_)
for interpreter in interpreters
for abi in abis
for platform_ in platforms
)
View on GitHub (pinned to f399c37189)
Solutions
- Raise the limit to accommodate the expected tag count, or pass limit=None if you trust the source.
- Reduce the breadth of the compressed tag (fewer alternatives per component) so the product stays within budget.
- Catch TooManyTagsError and either skip the tag or report it as too broad to handle.
- Compute the expected product (prod(len(c.split('.')) for c in tag.split('-'))) before parsing to fail fast with your own message.
Example fix
# before
parse_tag('a.b.c.d-x.y.z-p.q.r', limit=10) # TooManyTagsError: 24 > 10
# after - size the limit to the actual product, or trust source
from math import prod
count = prod(len(c.split('.')) for c in tag.split('-'))
parse_tag(tag, limit=count if count <= BUDGET else None) Defensive patterns
Strategy: validation
Validate before calling
from math import prod
def expected_count(tag: str) -> int:
return prod(len(c.split('.')) for c in tag.split('-'))
def within_budget(tag: str, limit: int) -> bool:
return expected_count(tag) <= limit Try / catch
from packaging.tags import TooManyTagsError
try:
parse_tag(tag, limit=BUDGET)
except TooManyTagsError:
skip_or_warn(tag) Prevention
- Compute the expansion product before parsing to fail fast.
- Raise the limit or pass None for trusted sources.
- Narrow overly-broad compressed tags before processing.
When it happens
Trigger: parse_tag('a.b.c.d-x.y.z-p.q.r', limit=10) where the product 4*3*2=24 > 10; parsing an adversarial or auto-generated compressed tag with many alternatives under a tight budget.
Common situations: A wheel resolver enforcing a tag-expansion budget to avoid quadratic blowups; processing untrusted/index-sourced tag strings; a generator that creates overly-broad compatibility tags.
Related errors
- limit must be non-negative
- Tag {tag!r} has an empty component: {component!r}
- Tag component {component!r} is not in sorted order per PEP 4
- Tag {tag!r} must have exactly three components
- Tag {tag!r} has an invalid interpreter: {interpreter!r}
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/ac03320e929aff6a.
Report an issue: GitHub.