Cookbook recipe

pg_dump Produces Incomplete Dump

Applies to PostgreSQL 13–17 Last reviewed May 2026 Grounded in source
Estimated investigation4 min

Scenario

Scenario A team uses pg_dump nightly for their application database. After a schema corruption incident, they restore from the dump. During restore, psql reports ERROR: relation "payments" does not exist and ERROR: role "app_user" does not…

Investigation Path

Scenario

A team uses pg_dump nightly for their application database. After a schema corruption incident, they restore from the dump. During restore, psql reports ERROR: relation "payments" does not exist and ERROR: role "app_user" does not exist. Post-restore, the application cannot connect because sequences are missing, permissions are gone, and extension-created objects are absent.

How to Identify

Conditions:

  • pg_dump excluded certain schemas via --exclude-schema or missed tables owned by other roles
  • pg_dump used --no-owner (drops owner info) or --no-privileges (drops ACLs)
  • Restore user lacks CREATE privileges — some objects silently skipped
  • Extension tables and functions missing because --exclude-schema=public excluded them
  • Sequences missing because dump was --data-only but schema had SERIAL/BIGSERIAL columns
  • pg_dump version mismatch: dumped with older pg_dump, restoring to newer PostgreSQL

Analysis Steps

-- Check what was actually dumped (list contents of dump file):
-- pg_restore --list backup.dump | grep -c "TABLE"    -- count table entries
-- pg_restore --list backup.dump | grep "SEQUENCE"    -- check sequences
-- pg_restore --list backup.dump | grep "ACL"         -- check permissions
-- pg_restore --list backup.dump | grep "EXTENSION"   -- check extensions

-- After restore: check what's missing
SELECT tablename FROM pg_tables WHERE schemaname = 'public'
EXCEPT
SELECT 'expected_table1' AS tablename UNION ALL SELECT 'expected_table2';

-- Check missing roles
SELECT rolname FROM pg_roles WHERE rolname IN ('app_user', 'reporting_user');

-- Check missing sequences
SELECT sequencename FROM pg_sequences WHERE schemaname = 'public';

-- Check extensions
SELECT extname, extversion FROM pg_extension;

-- Check database-level permissions
SELECT has_database_privilege('app_user', current_database(), 'CONNECT');

Pitfalls

  • pg_dump only dumps the specified database — it does NOT dump roles, tablespaces, or other databases. Use pg_dumpall for complete cluster-level dumps including global objects.
  • --no-owner and --no-privileges (often used for portability) strip all ownership and ACL information — objects will be owned by the restoring user only.
  • pg_dump with --schema=public excludes all other schemas. Application objects in app schema will be missing.
  • Extensions must be created before restoring extension-dependent objects. pg_dump includes CREATE EXTENSION but only if the restoring user has superuser privileges.
  • pg_dump is transactionally consistent — it’s not an issue — but the dump only captures the state at the start of the dump, not after any concurrent DDL.

Resolution Approach

Use pg_dumpall for complete cluster backups including global objects (roles, tablespaces). Use --format=directory or --format=custom for pg_restore flexibility. Always restore with a superuser to ensure all permissions apply correctly.

This is a Pro lesson

Get every Learning Pathway and cookbook recipe — grounded in PostgreSQL source code, with diagnostics, fixes, and prevention for each topic.

Continue this lesson to learn:

  • Mitigation Actions
  • All 36 Learning Pathway lessons
  • 170+ cookbook recipes
  • Source-grounded diagnostics & fixes

Secure checkout Cancel anytime Source-grounded

Career Impact

This scenario builds production judgment and operational confidence under pressure.

Open Career Dashboard →

Keep going

Related & next steps

Was this helpful?

← All cookbook recipes