Incident brief
Datetime field overflow
A date/time value was well-formed text, but named a value that doesn't exist on the calendar or falls outside PostgreSQL's supported range.
What lands in your log
ERROR: date/time field value out of range: "2024-02-30"
In 10 seconds
- What triggers it
- Cast a well-formed date string that names an impossible calendar day, such as February 30th.
- Fix
- Validate day-of-month against the actual month and leap-year rules before sending it to PostgreSQL, or just let PostgreSQL reject it and handle the error.
- Proof
- Reproduced on PostgreSQL 16.14 → Casting a well-formed but nonexistent calendar date (February 30th) was rejected with SQLSTATE 22008. The session was unaffected afterward.
Fix
What to do right now
Application-level steps for this error.
- Validate day-of-month against the actual month and leap-year rules before sending it to PostgreSQL, or just let PostgreSQL reject it and handle the error.
- Don't assume a regex/format check is enough, see the premium test for a second, unrelated way this same SQLSTATE is triggered.
- For application-computed dates (e.g. 'add N months'), check the result is still inside PostgreSQL's supported date range (4713 BC to 5874897 AD).
SELECT '2024-02-29'::date; -- 2024 is a leap yearFor this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
Datetime field overflow (22008) is statement-local: PostgreSQL does not retain the rejected value after the statement ends. Capture the exact bound value and statement position in application/server logs, then run this targeted validation before retrying.
Check field order and valid calendar range
Validate the specific value/shape that can raise this SQLSTATE.
SHOW DateStyle;
SHOW TimeZone;
-- Retest the exact rejected literal with an explicit target type.Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual, not paraphrased.
PostgreSQL 16 Documentation, Date/Time Types, Table 8.9
date, 4 bytes, date (no time of day), Low Value: 4713 BC, High Value: 5874897 ADRead the full section on postgresql.org →
The impossible calendar day
PostgreSQL parsed the year, month, and day fields from the text correctly, the problem is that February 2024 (a leap year) only goes up to the 29th, so day 30 doesn't exist. That's a field value out of range, not a parsing failure.Confirming the session still works
The out-of-range day value was caught during parsing, not after a write, so the session carries nothing over to its next statement.Reproduce & verify
A real, single-session PostgreSQL reproduction
A literal transcript of SQL run against a live PostgreSQL instance in an isolated lab. The commands below are exactly what was executed.
- 1Cast a well-formed date string that names an impossible calendar day, such as February 30th.
- 2PostgreSQL parses the text fine but finds no such day exists.
- 3SQLSTATE 22008 is reported.
One client: cast a date string that parses fine but names a day that doesn't exist.
-- No table needed: the failure happens purely at the type-cast stage.
SELECT 'no schema required' AS setup_note;SELECT '2024-02-30'::date;SELECT 1 AS session_still_alive;What PostgreSQL actually returned
setup_note
--------------------
no schema required
(1 row)ERROR: date/time field value out of range: "2024-02-30"
LINE 1: SELECT '2024-02-30'::date;
^ session_still_alive
----------------------
1
(1 row)22008 isn't only about impossible calendar days. This was tested directly: a date string that is a perfectly real calendar date, just one that falls outside the date type's supported range entirely.
Without this
Above: an impossible calendar day (February 30th) is rejected with SQLSTATE 22008.
With this, tested
Below: a real calendar date, just too far in the future for the type, is rejected with the very same SQLSTATE 22008.
- A second operational test: exact SQL, raw output, measured result, and engineer notes
- Fix that corrects the actual root cause: exact SQL, output, and verdict
- A manual-grounded production interpretation of the lab result
Card required. Cancel before day 7 and you are not charged.
Connected
Everything this error touches
Every page this SQLSTATE connects to: the concept that explains it, the runbooks that fix it, the parameters you tune to prevent it, and the sibling errors it travels with. All real cross-references. Jump straight in, or open the full interactive map.
Verification
- Last verified
- 2026-07-16 (Docker lab, PostgreSQL 16.14)
- Verification scope
- Verified against PostgreSQL 16.14 in an isolated lab environment
- Audit status
- reviewed
Went further?
Pro unlocks the second lab proof
Free page stops the bleeding. Pro adds the operational test, SQLSTATE audit, and deeper evidence, same error, more certainty.