ImportError: cannot import name 'StrEnum' from 'enum' (tested fix)
ImportError: cannot import name 'StrEnum' from 'enum' means the code runs on Python 3.10 or older; StrEnum arrived in 3.11. We tested the import, the usual (str, Enum) replacement and a fallback on Python 3.8, 3.11 and 3.13.
1. StrEnum only exists in Python 3.11+
import sys
print(sys.version.split()[0])
try:
from enum import StrEnum
print("ok:", StrEnum)
except ImportError as e:
print(f"{type(e).__name__}: {e}")
Output on the official python:3.8-alpine image:
3.8.20
ImportError: cannot import name 'StrEnum' from 'enum' (/usr/local/lib/python3.8/enum.py)
Output on Python 3.13.5:
3.13.5
ok: <enum 'StrEnum'>
enum.StrEnum was added in Python 3.11. On 3.10 and older the import fails. Check python3 --version where the error happens (server, Docker image, CI runner); it is often older than your own machine.
2. Fix: subclass str and Enum
from enum import Enum
class Color(str, Enum): # works on every Python 3
RED = "red"
BLUE = "blue"
print(Color.RED == "red", Color("blue"))
print(Color.RED.value, f"{Color.RED.value}")
Output:
True Color.BLUE
red red
Same output on 3.8. Members compare equal to plain strings, and .value is the string.
3. Gotcha: str() and f-strings of a (str, Enum) member
import sys
from enum import Enum
class A(str, Enum):
RED = "red"
print(sys.version.split()[0], "|", str(A.RED), "|", f"{A.RED}", "|", "%s" % A.RED)
Output on 3.13.5, 3.8.20 and 3.11.17:
3.13.5 | A.RED | A.RED | A.RED
3.8.20 | A.RED | red | A.RED
3.11.17 | A.RED | A.RED | A.RED
str() gives A.RED, not red, on every version. The f-string result changed in 3.11: on 3.8 it gave red, on 3.11+ it gives A.RED. If you upgrade Python with a (str, Enum) class, f-strings that built URLs, file names or SQL from members silently change. StrEnum gives red for both:
from enum import Enum, StrEnum
class A(str, Enum):
RED = "red"
class B(StrEnum):
RED = "red"
print(str(A.RED), f"{A.RED}", "|", str(B.RED), f"{B.RED}")
Output:
A.RED A.RED | red red
4. Fix for code that must run on old and new Python
from enum import Enum
try:
from enum import StrEnum
except ImportError: # Python < 3.11
class StrEnum(str, Enum):
def __str__(self):
return self.value
class Color(StrEnum):
RED = "red"
print(Color.RED == "red", str(Color.RED), f"{Color.RED}")
Output:
True red red
We ran this block unchanged on 3.8 and 3.13; both printed the line above. The __str__ override makes the fallback behave like the real StrEnum for str() and f-strings. (The real one also adds auto() producing the lower-case member name; in the fallback auto() gives '1' on 3.13, so give explicit values.)
Related: ImportError: cannot import name and cannot import name 'UTC' from 'datetime' (also new in 3.11).
Frequently asked questions
Why can't I import StrEnum from enum?
enum.StrEnum was added in Python 3.11. On 3.10 and older it does not exist.
What can I use instead of StrEnum?
class Color(str, Enum). Add def __str__(self): return self.value if you need str() and f-strings to give the value.
Why does my (str, Enum) f-string print Color.RED?
Since Python 3.11, format() of a mixed-in str Enum uses the enum's str(), which is Color.RED. On 3.8 it gave the value.
Written with AI assistance. Measured on 2026-10-22 with Python 3.13.5 on Debian and the official python:3.8-alpine (3.8.20) and python:3.11-alpine (3.11.17) images: importing StrEnum, a (str, Enum) class, str()/f-string/% formatting of members, and a try/except fallback. Every block was run verbatim and its output pasted unedited. PlainHeaders is our extension; Python is free.