Odoo Insights

Odoo backups that break your environment how to avoid them

A single wrong backup or restore step can wipe your Odoo data or lock your system. This guide shows the most common backup mistakes and how to avoid them before they break your operations.

2026-05-13 · 8 minutes

The real cost of a broken Odoo backup

You run the backup script from the documentation. Everything looks fine. Then you restore to a test server and Odoo crashes with psycopg2.OperationalError: could not connect to server: Connection refused. Suddenly your live production data is locked out and your team can’t process orders or shipments.

This isn’t rare. It happens when the backup copies only part of the system, mixes versions, or restores to the wrong environment. The result is downtime, lost work, and sometimes unrecoverable data loss. The mistake isn’t the backup itself—it’s the mismatch between what was backed up and where it’s restored.

Common symptoms you’ve hit this problem:

  • Odoo shows database connection failed after restore
  • Modules fail to load with ImportError: Module not found
  • Users see blank pages or 500 errors on restored site
  • Custom reports or integrations (like your ecommerce connector) stop working
  • PostgreSQL errors about missing tables or functions

What usually goes wrong during backup and restore

Mismatched Odoo versions

You backup a production site running Odoo 16.0 and restore it to a staging server on 15.0. The restore finishes without errors, but when you start Odoo, modules fail because the code expects version 16.0 features. This often happens when teams use different Odoo versions across environments or upgrade one environment but not others.

Partial backups

You copy only the PostgreSQL database file .dump but forget the filestore folder where Odoo stores attachments, images, and PDFs. After restore, all file fields show broken links. Users can’t view product images or download invoices.

Wrong restore target

You restore a production backup into your development server that already has custom modules in /odoo-custom-addons. The restore overwrites those modules, wiping weeks of development work. This is especially risky if your team follows the Odoo implementation best practices and keeps customizations separate.

Permissions and ownership drift

After restore, Odoo runs as user odoo but the PostgreSQL role has a different password or the file permissions on /var/lib/odoo were changed. The result is Permission denied errors when Odoo tries to write attachments or logs.

Timing and concurrency issues

You backup while users are logged in and Odoo is writing to the database. The dump is inconsistent: some tables reflect the state at 10:00 a.m., others at 10:05 a.m. When restored, Odoo shows orphaned records or fails integrity checks with psycopg2.errors.ForeignKeyViolation.

Quick checks to confirm you have a restore problem

Before you touch anything else, run these three checks. They take less than two minutes and tell you if your restore failed silently.

Check 1: Can Odoo start without errors?

Start Odoo in the foreground with debug mode:

sudo -u odoo /odoo/odoo-bin -c /etc/odoo/odoo.conf --log-level=debug

Success: Odoo prints Initiating shutdown and exits cleanly. If you see Database connection failed or Module X cannot be loaded, the restore is incomplete.

Check 2: Can you log in as admin?

Open the restored site in a browser. Try to log in as admin with the default password. If you get Invalid credentials, the user table wasn’t restored or the password was reset during restore.

Check 3: Do attachments and images work?

Go to a product or invoice and try to view or download an attachment. If you see a broken image icon or 404 Not Found, the filestore folder wasn’t restored or the web server can’t read it.

If any check fails, stop using the restored environment immediately. Do not run any more operations until you confirm the restore is complete and consistent.

Step-by-step fix for a broken restore

Step 1 — Roll back and isolate

If the restore is on a live server, shut down Odoo and PostgreSQL to prevent further writes:

sudo systemctl stop odoo postgresql

Move the restored data aside so you don’t overwrite it accidentally:

sudo mv /var/lib/odoo/filestore /var/lib/odoo/filestore_bad_restore
sudo mv /var/lib/postgresql/14/main /var/lib/postgresql/14/main_bad_restore

Step 2 — Rebuild the environment from scratch

Create a clean database and filestore:

sudo -u postgres createdb odoo_prod_restore
sudo -u postgres psql -d odoo_prod_restore -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
sudo mkdir -p /var/lib/odoo/filestore/odoo_prod_restore
sudo chown -R odoo:odoo /var/lib/odoo/filestore/odoo_prod_restore

Step 3 — Restore the database dump

Use pg_restore with the correct version flags. Replace backup.dump with your actual file:

sudo -u postgres pg_restore --no-owner --no-privileges --clean --if-exists -d odoo_prod_restore backup.dump

What this does: --clean drops existing objects first, --if-exists avoids errors if objects don’t exist, --no-owner prevents permission conflicts.

Step 4 — Restore the filestore

Copy the attachments folder to the correct location:

sudo rsync -av /path/to/backup/filestore/ /var/lib/odoo/filestore/odoo_prod_restore/

Verify: Check that the folder contains subfolders named like 00/00/ and files with names like 000000ab000000cd00000001.0.

Step 5 — Update Odoo config file

Edit /etc/odoo/odoo.conf and set:

[options]
db_name = odoo_prod_restore
data_dir = /var/lib/odoo/filestore/odoo_prod_restore

Step 6 — Start Odoo and verify

Start Odoo and check logs:

sudo systemctl start odoo
journalctl -u odoo -n 50 --no-pager

Success signs: Odoo prints HTTP service (werkzeug) running on ... and no module load errors. Log in as admin and confirm attachments and reports work.

How to prevent this mistake next time

Use this checklist before every backup and restore. Treat it like a pre-flight checklist for an airplane—skip one item and you risk a crash.

Before backup

  • Confirm versions: Run odoo-bin --version on source and target servers. They must match exactly.
  • Check disk space: Ensure /var/lib has at least 20% free space for the dump and filestore.
  • Stop Odoo gracefully: Run sudo systemctl stop odoo 30 seconds before backup to flush writes.
  • Backup both database and filestore: Use a script that copies PG_DUMP output and the entire filestore folder.
  • Validate backup size: After backup, compare the dump size to the previous day. A sudden drop may mean the dump is empty or corrupted.

Before restore

  • Create a new empty database: Never restore into an existing database unless you intend to overwrite it completely.
  • Check PostgreSQL locale: Run sudo -u postgres psql -l on both servers. If locales differ, you may get encoding errors like invalid byte sequence for encoding UTF8.
  • Test restore in staging first: Restore to a non-production server that mirrors production in version and modules. If it works there, it’s safe to restore to production.
  • Verify module list: After restore, run odoo-bin -i base --show-odoo-version and compare module versions to production. Any mismatch means the restore is incomplete.
  • Set correct ownership: After restore, run sudo chown -R odoo:odoo /var/lib/odoo/filestore/* and sudo chmod -R 750 /var/lib/odoo/filestore.

If your team follows custom addon best practices, add one more step: restore the /odoo/custom/addons folder from version control after the database restore to avoid overwriting custom code.

When to seek help instead of fixing yourself

Some restore failures require deeper PostgreSQL or Odoo expertise. If you see any of these signs, pause and escalate:

  • Odoo crashes with psycopg2.errors.DuplicateObject or psycopg2.errors.UndefinedFunction during startup
  • The database dump is corrupted and pg_restore exits with pg_restore: error: unrecognized data block type
  • PostgreSQL refuses to start after restore with FATAL: could not open directory "pg_tblspc": No such file or directory
  • You restored from a backup that was created on a different PostgreSQL major version (e.g., 14 vs 15)
  • The restore works but custom reports or integrations (like your payment gateway) return 500 errors

If any of these occur, do not proceed. Contact your Odoo partner or a certified administrator. Provide them with:

  • The exact Odoo and PostgreSQL versions on source and target
  • The full pg_restore command and its output
  • The Odoo logs from the failed startup (journalctl -u odoo -n 200)
  • A screenshot of the error and the URL path where it occurs

Attempting to force-fix these issues without expertise can lead to permanent data corruption or extended downtime, which can impact your Odoo subscription costs if support hours are exceeded.

One immediate action you can take today

Open your backup script now and compare it to the checklist above. If it doesn’t include both the database dump and the entire filestore folder, update it today. Then run a test restore on a disposable VM or staging server. Confirm you can log in, view attachments, and run reports. If it fails, you’ve caught the problem before it affects production.

Remember: a backup that isn’t tested is not a backup. It’s a gamble on your business continuity. Spend 15 minutes today to avoid hours or days of downtime tomorrow.

Practical Next Step

Check your backup script today

Discuss Your Odoo Scope

FAQ

What’s the difference between a database dump and a filestore backup?

A database dump (backup.dump) contains all your business data: customers, products, orders, invoices, and settings. The filestore folder contains attachments, images, PDFs, and binary files uploaded by users. If you only backup the dump, product images and invoices will appear broken after restore.

Why does Odoo show <code>Module not found</code> after restore even though the module exists in /odoo-custom-addons?

This usually happens when the module was installed in the database but the __manifest__.py file or module path was changed during restore. Odoo reads the manifest from the filesystem to determine version and dependencies. If the path in the manifest doesn’t match the actual filesystem path, the module fails to load. Always restore the /odoo/custom/addons folder from version control after the database restore.

Can I restore a backup from Odoo 15 to a server running Odoo 16?

No. Odoo 15 and 16 have different module APIs and database schemas. Restoring a 15 dump into 16 will cause module load failures and possibly data corruption. Always restore to the exact same Odoo version. If you need to migrate, use the official Odoo migration tools or upgrade the destination server to 15 first, then migrate to 16 separately.

I restored the backup but PostgreSQL won’t start. What should I check?

First, check PostgreSQL logs with journalctl -u postgresql -n 50. Common causes: missing data directory, wrong ownership on /var/lib/postgresql, or a corrupted postgresql.conf. If the data directory is missing, you may have restored to the wrong path. If the logs show FATAL: could not open directory "pg_tblspc", the tablespace links are broken—this requires PostgreSQL expertise to repair.

Is there a simple way to automate safe backups without scripting?

Yes. Use the Odoo built-in backup tool with the right flags. Run on the server:

sudo -u odoo /odoo/odoo-bin -c /etc/odoo/odoo.conf --backup-all --backup-dir /var/backups/odoo
This creates a timestamped dump and copies the filestore to /var/backups/odoo. It’s safer than manual scripts because it flushes writes and handles permissions automatically. Still, test the restore manually at least once a month.