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.