Odoo upgrade error
time zone "Asia/Calcutta" not recognized
Last updated: October 2026
Older Odoo versions offered legacy time zone names. Newer Linux images no longer install them, so PostgreSQL and Python stop recognizing values your database already stores.
This page is part of our guide on how to upgrade Odoo Community Edition. It explains what triggers the error, how to fix it by hand, and what an automated migration does about it.
The error
psycopg2.errors.InvalidParameterValue: time zone "Asia/Calcutta" not recognizedFrom Python code the same problem shows up as pytz.exceptions.UnknownTimeZoneError: 'Asia/Calcutta'. Other legacy names behave the same way, for example US/Eastern, Asia/Saigon or Europe/Kiev.
- Raised by
- PostgreSQL (
AT TIME ZONE) orpytz.timezone() - Affected setups
- Odoo or PostgreSQL on Ubuntu 24.04 without
tzdata-legacy, including the odoo:18.0 and odoo:19.0 Docker images - Upgrade hops
- Seen on 18→19; can appear in any version on such a server
When you see it
Asia/Calcutta is an old alias of Asia/Kolkata. Odoo builds its time zone list from pytz, so older Odoo versions offered the alias and users picked it for themselves, their company partner or a working-hours calendar. The value is stored as plain text in columns such as res_partner.tz, resource_calendar.tz and resource_resource.tz.
Ubuntu 24.04 moved these aliases out of the tzdata package into a separate tzdata-legacy package that is not installed by default. PostgreSQL on Debian and Ubuntu reads the system time zone database, and so does the distribution's python3-tz. On such a system any SQL that converts with a stored zone fails. Odoo 19 does this itself, for example when it computes the state of activities from mail_activity.user_tz. Migration scripts that convert dates into an employee's local time hit it too: we traced a failed 18→19 run to exactly this, while computing HR work entry dates.
Root cause
The data is valid; the server is missing the names. Check which legacy values your database holds:
SELECT tz, count(*) FROM res_partner
WHERE tz IN ('Asia/Calcutta', 'Asia/Saigon', 'Asia/Katmandu',
'US/Eastern', 'US/Central', 'US/Pacific')
GROUP BY tz;And check whether PostgreSQL knows a name:
SELECT now() AT TIME ZONE 'Asia/Calcutta';How to fix it
Option 1: install the legacy names on the server
On the machine or container that runs PostgreSQL, and on the one that runs Odoo if it is different:
apt-get update
apt-get install tzdata-legacyRestart PostgreSQL and Odoo afterwards. This changes no data and fixes every legacy name at once. If you run the official Odoo Docker image, add the package in your own Dockerfile so it survives image updates.
Option 2: switch the data to canonical names
This makes the database independent of the server packages. Odoo stores time zones in several tables, so update every column that holds one:
Before you change anything: Back up the database before running any UPDATE or INSERT below, and try it on a copy first. These statements change data directly, outside the Odoo ORM.
DO $
DECLARE
r record;
m record;
BEGIN
FOR m IN SELECT * FROM (VALUES
('Asia/Calcutta', 'Asia/Kolkata'),
('Asia/Saigon', 'Asia/Ho_Chi_Minh'),
('Asia/Katmandu', 'Asia/Kathmandu'),
('US/Eastern', 'America/New_York'),
('US/Central', 'America/Chicago'),
('US/Pacific', 'America/Los_Angeles')
) AS t(old_tz, new_tz)
LOOP
FOR r IN
SELECT c.table_name, c.column_name
FROM information_schema.columns c
JOIN information_schema.tables t
ON t.table_schema = c.table_schema AND t.table_name = c.table_name
WHERE c.table_schema = 'public'
AND t.table_type = 'BASE TABLE'
AND c.column_name IN ('tz', 'user_tz', 'date_tz', 'event_tz', 'timezone')
AND c.data_type IN ('character varying', 'text')
LOOP
EXECUTE format('UPDATE %I SET %I = %L WHERE %I = %L',
r.table_name, r.column_name, m.new_tz,
r.column_name, m.old_tz);
END LOOP;
END LOOP;
END $;Extend the list with any other legacy names the first query found. Doing both options is the safest choice: the package for anything you missed, the data change for the long run.
How OCU handles it
Since the end of September 2026 the OCU runner images install tzdata-legacy, so the embedded PostgreSQL and Python resolve legacy names during the migration and the upgrade no longer fails on them. An image-level test checks this for each runner version.
OCU does not rewrite the stored values. The migrated database still contains Asia/Calcutta where your users chose it, so if your new Odoo server is based on Ubuntu 24.04, apply option 1 or option 2 there.
A free test migration shows whether your database runs into this or any other upgrade error before you change anything on your production server.
Frequently asked questions
- Is Asia/Calcutta a wrong time zone?
- No. It is an official alias of Asia/Kolkata in the IANA time zone database and gives the same offset. It is only missing because some Linux distributions no longer install the alias names by default.
- Why does the error only appear after moving to a new server?
- Older server images installed the alias names as part of tzdata. Ubuntu 24.04 moved them into the tzdata-legacy package, so a database that worked on the old server fails as soon as PostgreSQL or Python on the new server needs to resolve the stored name.
- Do I need to change anything in Odoo itself?
- No code change is needed. Either install tzdata-legacy on the server or update the stored values to the canonical names. Users can also pick the canonical zone in their preferences afterwards.
Related
Find upgrade errors before your production run
Upload a backup and run a free test migration. You get the upgraded database, the full log and every warning, with no change to your live system.
Start your free test migration