GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Assertion `year >= 1' failed in 'days_before_year'` when unpickling datetime with year 0 · Issue #160358 · python/cpython

Assertion year >= 1' failed in 'days_before_year' when unpickling datetime with year 0 #160358

New issue
Copy link
New issue
Copy link
Open
Open
Assertion year >= 1' failed in 'days_before_year' when unpickling datetime with year 0#160358
Copy link
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump

Description

@ashm-dev
ashm-dev
opened on Oct 22, 2026
Issue body actions

Crash report

_datetimemodule.c does not validate that MINYEAR <= year <= MAXYEAR when reconstructing a datetime.datetime object from serialized bytes (unpickling).

This allows instantiating an invalid datetime object with year == 0. Subsequent calls to methods such as .toordinal() hit the C-level assertion assert(year >= 1) in days_before_year(), crashing the interpreter process with SIGABRT in debug / -X dev builds.

Steps to Reproduce

Run the following script with ./python -X dev:

import datetime
import pickle

dt = datetime.datetime(2023, 10, 1)
data = pickle.dumps(dt)

# Replace year 2023 (0x07E7) with 0 (0x0000)
corrupted_data = data.replace(b'\x07\xe7', b'\x00\x00')

obj = pickle.loads(corrupted_data)
obj.toordinal()

Actual Behavior

The process aborts due to an assertion failure:

python: ./Modules/_datetimemodule.c:477: int days_before_year(int): Assertion `year >= 1' failed.
Fatal Python error: Aborted

Current thread 0x00007f8943602400 [python] (most recent call first):
  File "<python-input-0>", line 11 in <module>
  File "/home/boss/projects/oss/cpython/main/Lib/_pyrepl/console.py", line 231 in runcode
  File "/home/boss/projects/oss/cpython/main/Lib/_pyrepl/console.py", line 288 in runsource
  File "/home/boss/projects/oss/cpython/main/Lib/code.py", line 324 in push
  File "/home/boss/projects/oss/cpython/main/Lib/_pyrepl/simple_interact.py", line 149 in run_multiline_interactive_console
  File "/home/boss/projects/oss/cpython/main/Lib/_pyrepl/main.py", line 58 in interactive_console

Current thread's C stack trace (most recent call first):
  Binary file "./python", at __interceptor_backtrace+0x4c [0x55a217378b2c]
  Binary file "./python", at _Py_DumpStack+0x10c [0x55a21803e9c4]
  Binary file "./python", at +0x1a523c1 [0x55a2180b83c1]
  Binary file "/usr/lib/libc.so.6", at +0x3e6f0 [0x7f894323e6f0]
  Binary file "/usr/lib/libc.so.6", at +0x9a11c [0x7f894329a11c]
  Binary file "/usr/lib/libc.so.6", at gsignal+0x20 [0x7f894323e5d0]
  Binary file "/usr/lib/libc.so.6", at abort+0x26 [0x7f8943225685]
  Binary file "/usr/lib/libc.so.6", at +0x26704 [0x7f8943226704]
  Binary file "/usr/lib/libc.so.6", at __assert_fail+0xc2 [0x7f89432361f2]
  Binary file "./python", at +0x1ab4039 [0x55a21811a039]
  Binary file "./python", at +0x115f759 [0x55a2177c5759]
  Binary file "./python", at +0x111c356 [0x55a217782356]
  Binary file "./python", at _Py_VectorCallInstrumentation_StackRefSteal+0x180 [0x55a217c96a58]
  Binary file "./python", at +0x1671568 [0x55a217cd7568]
  Binary file "./python", at _PyEval_EvalFrameDefault+0x4a1 [0x55a217c9a059]
  Binary file "./python", at PyEval_EvalCode+0x2d9 [0x55a217c956e1]
  Binary file "./python", at +0x1621beb [0x55a217c87beb]
  Binary file "./python", at _Py_BuiltinCallFastWithKeywords_StackRef+0x155 [0x55a217c9773d]
  Binary file "./python", at +0x16bcdf4 [0x55a217d22df4]
  Binary file "./python", at _PyEval_EvalFrameDefault+0x4a1 [0x55a217c9a059]
  Binary file "./python", at +0x162fc40 [0x55a217c95c40]
  Binary file "./python", at +0x111f20a [0x55a21778520a]
  Binary file "./python", at +0x1a1c6ca [0x55a2180826ca]
  Binary file "./python", at +0x1a1ae13 [0x55a218080e13]
  Binary file "./python", at Py_RunMain+0xd79 [0x55a21807f051]
  Binary file "./python", at +0x1a19cf9 [0x55a21807fcf9]
  Binary file "./python", at Py_BytesMain+0xd5 [0x55a21807ffbd]
  Binary file "/usr/lib/libc.so.6", at +0x27781 [0x7f8943227781]
  Binary file "/usr/lib/libc.so.6", at __libc_start_main+0x89 [0x7f89432278b9]
  Binary file "./python", at _start+0x25 [0x55a217328fa5]
fish: Job 1, './python -X dev' terminated by signal SIGABRT (Abort)

Expected Behavior

pickle.loads() should validate year against MINYEAR (1) and MAXYEAR (9999) during state unpacking and raise ValueError: year 0 is out of range, consistent with the standard datetime(year, month, day) constructor.

Environment

  • CPython version: 3.16.0a1+dev (heads/main:ad101c3b307)
  • OS: Linux
  • Build: CC=clang CXX=clang++ LDFLAGS='-fuse-ld=lld' ./configure --with-tail-call-interp --with-pydebug --with-address-sanitizer --with-undefined-behavior-sanitizer

CPython versions tested on:

CPython main branch, 3.16, 3.15, 3.14, 3.13, 3.12, 3.11

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.16.0a1+dev (heads/main:ad101c3b307, Oct 22 2026, 23:57:40) [Clang 23.1.3 ]

Activity

  1. ashm-dev
    added
    type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
    on Oct 22, 2026
  2. picnixz
    added
    extension-modulesC modules in the Modules dirC modules in the Modules dir
    on Oct 22, 2026
  3. picnixz
    added this to Date and time issues 🕰️on Oct 22, 2026
  4. picnixz commented on Oct 22, 2026

    @picnixz
    picnixz
    on Oct 22, 2026
    Member
    More actions

    I honestly don't think it's relevant here. You need to change the pickle representation so I would expect that to crash. It's within the same realm as crashes due to code.__replace__,

    I would appreicate if you refrain from submitting such issues in the future as they are mostly non-issues or outside of what we expect to be relevant (lots of similar issues for code.__replace__ were rejected as well).

    Nonetheless, I'm leaving it at the discretion of @StanFromIreland but please don't open a PR yet.

    Reacted by Peter Bierma
  5. picnixz
    added
    pendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is provided
    on Oct 22, 2026
  6. jelle-openai commented on Oct 23, 2026

    @jelle-openai
    jelle-openai
    on Oct 23, 2026
    Contributor
    More actions

    This is also reproducible without pickling:

    Python 3.12.13 (main, Mar 25 2026, 03:16:06) [Clang 22.1.1 ] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from datetime import datetime
    >>> 
    >>> dt = datetime(bytes([0, 0, 1, 1]) + bytes(6))
    >>> dt.ctime()
    zsh: segmentation fault  python3

    Though this is an undocumented constructor format that appears to exist solely to support pickling. Still, I'd argue it shouldn't be possible to segfault Python with just passing a bytes object to the datetime constructor.

  7. picnixz commented on Oct 23, 2026

    @picnixz
    picnixz
    on Oct 23, 2026
    Member
    More actions

    Ok, with the bytes approach, I agree that we shouldn't crash (it's possible that someone just passes the wrong object)

    Reacted by Stan Ulbrych
  8. picnixz
    removed
    pendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is provided
    on Oct 23, 2026
  9. StanFromIreland commented on Oct 23, 2026

    @StanFromIreland
    StanFromIreland
    on Oct 23, 2026
    Member
    More actions

    In that case, yes please open a PR.

  10. StanFromIreland
    changed the title [-]Crash (SIGABRT): Assertion `year >= 1' failed in `days_before_year` when unpickling datetime with year 0[/-] [+]Assertion `year >= 1' failed in 'days_before_year'` when unpickling datetime with year 0[/+] on Oct 23, 2026
  11. ashm-dev commented on Oct 25, 2026

    @ashm-dev
    ashm-dev
    on Oct 25, 2026
    ContributorAuthor
    More actions

    9. In that case, yes please open a PR.

    Got it, thanks. Currently capped at the PR limit, so I'll put it up once a slot frees up (if no one snags it first)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump

    Projects

    • Date and time issues 🕰️
      Status
      No status
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.