IndexError: no such group (Python re, tested)
IndexError: no such group from Python's re module means you asked a match object for a group the pattern doesn't define. We measured it on Python 3.13.5, along with the related re.sub errors, which use different messages and even different exception types.
1. match.group() with a number or name the pattern doesn't have
import re
m = re.search(r"(\d+)-(\d+)", "range 10-20")
print(m.group(1), m.group(2))
for g in [3, "year"]:
try:
m.group(g)
except IndexError as e:
print(f"group({g!r}): IndexError: {e}")
Output:
10 20
group(3): IndexError: no such group
group('year'): IndexError: no such group
Measured on Python 3.13.5: the pattern has two groups, so group(3) fails, and group("year") fails because nothing is named year. Both give IndexError: no such group. Count the ( in your pattern ((?:...) groups don't count), or print m.groups() / m.groupdict().
2. re.sub replacement strings: a different message for each mistake
import re
for repl in [r"\2", r"\g<year>", r"\3"]:
try:
print(re.sub(r"(\d+)", repl, "a1b"))
except (re.error, IndexError) as e:
print(f"sub repl {repl!r}: {type(e).__module__}.{type(e).__name__}: {e}")
print(re.sub(r"(\d+)", r"[\1]", "a1b"))
print(re.sub(r"(\d+)", r"\g<1>0", "a1b")) # \10 would mean group 10
try:
re.sub(r"(\d+)", r"\10", "a1b")
except re.error as e:
print(r"\10:", e)
Output:
sub repl '\\2': re.PatternError: invalid group reference 2 at position 1
sub repl '\\g<year>': builtins.IndexError: unknown group name 'year'
sub repl '\\3': re.PatternError: invalid group reference 3 at position 1
a[1]b
a10b
\10: invalid group reference 10 at position 1
Measured: in a replacement string, a missing numbered group raises re.PatternError: invalid group reference N (3.13's name for re.error), but a missing named group raises a plain IndexError: unknown group name, so except re.error alone won't catch it. Also \10 means group 10, not group 1 followed by 0; write \g<1>0.
3. Named groups and optional groups
import re
pat = re.compile(r"(?P<user>\w+)@(?P<host>[\w.]+)")
m = pat.search("mail ada@example.com")
print(m.group("user"), m["host"], m.groupdict())
try:
m.group("domain")
except IndexError as e:
print("typo'd name:", e)
m2 = re.search(r"(a)|(b)", "b")
print("unmatched optional group:", m2.group(1)) # None, not an error
Output:
ada example.com {'user': 'ada', 'host': 'example.com'}
typo'd name: no such group
unmatched optional group: None
Measured: a typo in a group name gives the same no such group. A group that exists but didn't take part in the match is not an error: it returns None, so check for that before calling string methods on it.
Frequently asked questions
What does IndexError: no such group mean in Python re?
You asked a match for a group number or name the pattern doesn't define. We measured group(3) on a two-group pattern and group('year') with no such named group, both raising it on Python 3.13.5.
Why does re.sub say invalid group reference?
The replacement string refers to a group number the pattern doesn't have, e.g. \2 with one group. We measured re.PatternError: invalid group reference 2.
How do I put a digit right after a group in re.sub?
Use \g<1>0; \10 means group 10. We measured \10 failing and \g<1>0 giving a10b.
Why doesn't except re.error catch unknown group name?
A missing named group in a re.sub replacement raises plain IndexError: unknown group name. We measured it on Python 3.13.5; catch (re.error, IndexError).
Written with AI assistance. Measured on 2026-10-09 with Python 3.13.5 on Linux: match.group with a missing number and name, re.sub replacements with missing numbered and named groups and \10 vs \g<1>0, named groups, and an optional group that didn't match. Every block was run verbatim and its output pasted from that run. PlainHeaders is our extension; everything else here is built-in Python.