Python 3.11 End of Life: Dates and How to Upgrade

Python 3.11 reaches end of life in October 2027 and gets security fixes only. What that means, when to move, and what breaks going to 3.12 or later.

Python 3.11 reaches end of life in October 2027. Until then it receives security fixes only, and after that the core team stops releasing fixes of any kind. The sensible time to plan the move is now, while you can choose the date.

For every version’s dates, see the Python end-of-life dates page. The neighbouring versions are covered in Python 3.10 end of life and Python 3.12 end of life.

Python 3.11 dates

MilestoneDate
Released24 October 2022
Last regular bugfix release (3.11.9)2 April 2024
Latest release when checked (3.11.18)25 October 2026
End of life1 October 2027 (scheduled)

The dates come from PEP 664 and the Python Developer’s Guide. Python 3.11 received bugfix releases for about 18 months. Since then it has received source-only security releases, provided irregularly as needed, until about five years after the first release.

What end of life means in practice

Nothing stops on the day. Your code, environments and containers keep running. What changes:

  • No interpreter fixes. A vulnerability found in 3.11 is fixed in newer versions only.
  • Libraries move on. The latest NumPy (2.5.4), SciPy (1.18.1) and Django (6.1.3) require Python 3.12 or later, according to PyPI on 4 November 2026. pandas, Pillow, Matplotlib and scikit-learn still support 3.11, for now.
  • Platforms follow. Check which versions your hosting runtime, CI images and base images still offer.

Which version to move to

TargetStatus on 4 November 2026End of life
3.12Security fixes onlyOctober 2028
3.13Security fixes only (since 1 October 2026)October 2029
3.14Bugfix releasesOctober 2030
3.15Bugfix releases, released on 9 October 2026October 2031

Moving to 3.12 is the smallest jump, but it is already in its security-only phase, so you would be upgrading again within a year of 3.11. For the differences between the two newest versions, see Python 3.14 vs 3.15 and what is new in Python 3.15.

What breaks going from 3.11 to 3.12

  • Removed modules: distutils, imp, asyncore, asynchat and smtpd.
  • Removed aliases: the unittest names failUnless, failIf, assertEquals, assertNotEquals, assertRegexpMatches, assertRaisesRegexp and the other aliases listed in the 3.12 What’s New. Rename to assertTrue, assertFalse, assertEqual, assertNotEqual, assertRegex and assertRaisesRegex.
  • No setuptools in new virtual environments. If your code imports setuptools or pkg_resources, declare it as a dependency. You can see the difference by creating one environment on each version:
$ python3.11 -m venv venv311 && venv311/bin/python -m pip list --format=freeze
pip==26.2.2
setuptools==79.0.1

$ python3.12 -m venv venv312 && venv312/bin/python -m pip list --format=freeze
pip==26.2.2

Version numbers will differ on your machine; the point is that setuptools is absent on 3.12.

What breaks going on to 3.13 and 3.14

If you jump past 3.12 you meet these as well, listed by the version that made the change:

VersionRemoved or changed
3.1319 modules under PEP 594, including cgi, cgitb, crypt, imghdr, pipes and telnetlib; also lib2to3 and the 2to3 tool; locals() in a function now returns an independent snapshot
3.14The asyncio child watchers, ast.Num and ast.Str, pkgutil.get_loader, urllib.request.URLopener; on Unix other than macOS the default multiprocessing start method is now forkserver

More detail on each is in Python 3.13 end of life and what is new in Python 3.14.

An upgrade checklist

  1. Find where you run 3.11: python --version in each environment, requires-python in pyproject.toml, FROM python:3.11 in Dockerfiles, and the version settings in CI.
  2. Run your tests on the target version first, with warnings turned into errors: python -W error -m pytest. A deprecation warning in your own code then fails a test instead of scrolling past.
  3. Check each dependency supports the target. Installing into a fresh virtual environment shows resolver conflicts quickly.
  4. Run Ruff with the UP rules to modernise syntax: ruff check --select UP --target-version py313 .
  5. Update CI, Docker and deployment settings together, then roll out.

If you need several versions side by side while you migrate, see pyenv vs uv.

Frequently Asked Questions

When does Python 3.11 reach end of life?

October 2027. The Python Developer’s Guide schedules it for 1 October 2027, and PEP 664 says security fixes continue until about five years after the 24 October 2022 release. Scheduled dates can be adjusted, so check the live table before planning around a specific day.

Is Python 3.11 still supported?

Yes, for security fixes only. The last regular bugfix release was 3.11.9 on 2 April 2024. Since then 3.11 has received source-only security releases, the most recent being 3.11.18 on 25 October 2026.

Which Python version should I move to from 3.11?

Python 3.13 (supported until October 2029) or 3.14 (supported until October 2030) are the practical targets. Python 3.15, released on 9 October 2026, is supported until October 2031, and the main scientific libraries already publish wheels for it.

What breaks when upgrading from Python 3.11 to 3.12?

distutils, imp, asyncore, asynchat and smtpd were removed, along with long-deprecated unittest aliases such as assertEquals and failUnless. Virtual environments no longer include setuptools by default, so projects that import setuptools or pkg_resources at runtime must declare it as a dependency.

Do I have to upgrade from Python 3.11 now?

No. Your code keeps running after end of life, but the interpreter stops receiving security fixes. The latest NumPy, SciPy and Django already need Python 3.12 or later, so a project on 3.11 is held back on those. Plan the move within the year before the date.