This error occurs when a non-owner or non-superuser attempts to modify, drop, or comment on a PostgreSQL extension. Most commonly encountered during database dumps/restores or Rails migrations, it requires either ownership privileges or superuser permissions to resolve.
PostgreSQL extensions are database objects that have owners, just like tables or schemas. Only the owner (the user who created the extension) or a superuser can modify, drop, or manage an extension. When you attempt an extension operation without proper ownership rights, PostgreSQL denies the action with this error. This commonly occurs in two scenarios: (1) When restoring a database dump that includes extension comments or metadata that were created by a different user than the one running the restore, and (2) When running database migrations in applications like Rails where the migration user lacks extension ownership. In cloud-hosted PostgreSQL environments like Heroku, Railway, or Google Cloud SQL, this error is particularly common because the database user typically lacks superuser privileges for security reasons.
Connect to your PostgreSQL database and list all extensions with their owners:
SELECT extname, extowner::regrole FROM pg_extension;This shows which user owns each extension. Compare this to the user running your migrations.
If you are restoring from a pg_dump file, open the dump file (typically structure.sql or db/structure.sql in Rails) and remove any lines that start with COMMENT ON EXTENSION:
-- REMOVE THIS LINE:
-- COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';Extensions are already installed in PostgreSQL by default, so these comments are not necessary and only cause permission errors. After removing these lines, retry the restore.
If you are using Rails, modify your config/application.rb or db/structure.sql to skip extension-related statements:
# config/application.rb
config.active_record.schema_format = :ruby # Use schema.rb instead of structure.sqlAlternatively, if you must use structure.sql, ensure your dump process excludes extension definitions:
pg_dump --exclude-schema=information_schema --exclude-schema=pg_catalog DATABASE_NAME > dump.sqlIf you control the database and can temporarily grant superuser rights, do so during migration:
ALTER USER migration_user WITH SUPERUSER;
-- Run migrations
ALTER USER migration_user WITH NOSUPERUSER;Note: This approach is not available in managed databases like Heroku or Google Cloud SQL where superuser access is restricted.
For managed databases, install commonly-needed extensions to the template1 database before creating application databases:
psql -U postgres -d template1 -c "CREATE EXTENSION IF NOT EXISTS plpgsql;"
psql -U postgres -d template1 -c "CREATE EXTENSION IF NOT EXISTS uuid-ossp;"All new databases inherit extensions from template1, so your application user will not need to create them.
When writing migrations, use IF NOT EXISTS to safely handle extensions that may already be installed:
CREATE EXTENSION IF NOT EXISTS plpgsql;
CREATE EXTENSION IF NOT EXISTS uuid-ossp;Better yet, remove extension creation from migrations entirely if your hosting provider (Heroku, Railway, Supabase) pre-installs them. Check your provider's documentation for available extensions.
For PostgreSQL 13+, extensions can be marked as "trusted" by editing the extension's control file and adding trusted = true. This allows non-superuser database owners to create the extension. However, this requires access to the PostgreSQL server files and is not available on managed databases.
In Supabase and other managed PostgreSQL services, extensions are pre-installed with a special admin user. If you attempt to alter or drop them in migrations, you may encounter ownership conflicts. The safest approach is to check whether the extension already exists before creating it, or contact your hosting provider's support to pre-install specific extensions.
Cloud SQL for PostgreSQL restricts changing extension ownership via ALTER EXTENSION OWNER TO because superuser privileges are not exposed to users. If you need custom extensions, request them through the Cloud SQL console or use the Cloud SQL proxy with appropriate permissions.
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL