Fatal error on EDB Postgres (EPAS): has_schema_privilege crashes due to client-side schema filtering in InspectStage2
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
Research direction
Start with internal/inspect/stage2.go and internal/inspect/sql/schemas.sql, then trace how managedSchemas is passed from YAML and filtered after query execution. Verify the proposed server-side filtering against the EPAS reproduction, including proprietary package names. Done means Stage 2 no longer crashes on EPAS while managing only the configured schemas.
Written by the indexing model from the issue text.
Description
Describe the bug
When running ldap2pg (v6.5.1) against EnterpriseDB Postgres Advanced Server (EPAS versions 15, 16, 17, and 18), the synchronization fails with a fatal error during the schema inspection phase (Stage 2), even if schemas_query is strictly limited to [public].
time=2026-03-06T18:47:15.853Z level=DEBUG msg="Inspecting managed schemas." config=schemas_query database=postgres time=2026-03-06T18:47:15.853Z level=DEBUG msg="Reading values from YAML." time=2026-03-06T18:47:15.853Z level=DEBUG msg="Executing SQL query:\nSELECT nspname, rolname\nFROM pg_catalog.pg_namespace\nJOIN pg_catalog.pg_roles ON pg_catalog.pg_roles.oid = nspowner\n-- Ensure ldap2pg can use.\nWHERE has_schema_privilege(CURRENT_USER, nspname, 'USAGE')\nORDER BY 1;\n" time=2026-03-06T18:47:15.855Z level=ERROR msg="Fatal error." err="inspect: schemas: ERROR: schema \"dbms_alert\" does not exist (SQLSTATE 3F000)"
To Reproduce
Steps to reproduce the behavior:
- Provision an EDB Postgres Advanced Server cluster (e.g., using CloudNativePG with edb-postgres-advanced:18.1-standard-ubi9 image).
- Configure ldap2pg.yml to only manage the public schema (schemas_query: [public]).
- Run ldap2pg.
- It crashes immediately on dbms_alert, dbms_assert, aq$_agent, or any other EDB proprietary package.
Root Cause Analysis
We did some reverse engineering and found the exact bottleneck.
EPAS achieves Oracle compatibility by injecting proprietary PL/SQL packages (like dbms_alert, utl_file, aq$_agent) directly into pg_catalog.pg_namespace using a custom nspbodysrc column filled with '$EDBwrapped$' binaries.
In internal/inspect/stage2.go, ldap2pg fetches the managedSchemas from the YAML configuration into a Go slice. However, it then executes the hardcoded query from internal/inspect/sql/schemas.sql across the entire pg_namespace table:
SELECT nspname, rolname FROM pg_catalog.pg_namespace JOIN pg_catalog.pg_roles ON pg_catalog.pg_roles.oid = nspowner -- Ensure ldap2pg can use. WHERE has_schema_privilege(CURRENT_USER, nspname, 'USAGE') ORDER BY 1;
When the built-in Postgres C-function has_schema_privilege() evaluates these EDB package/schema hybrids, it cannot resolve them as standard schemas and throws a fatal transaction error (schema "dbms_alert" does not exist), crashing the whole query.
Because ldap2pg relies on client-side filtering (filtering the sq.Row() against managedSchemas slice after the query execution in Go), the query itself never survives the execution on an EPAS cluster.
Proposed Solution
Please consider changing the schema inspection logic to use server-side filtering.
If the managedSchemas list is passed to the schemas.sql query as an argument (e.g., AND nspname = ANY($1)), Postgres will filter the rows before evaluating has_schema_privilege().
This would prevent the C-function from touching unmanaged/proprietary schemas, making ldap2pg fully compatible with EDB Postgres Advanced Server and improving performance on standard Postgres instances with many schemas.
Current Workaround
Currently, the only way to make ldap2pg work on EPAS is to manually execute CREATE SCHEMA IF NOT EXISTS ... for all ~60 proprietary EDB objects (dbms_%, utl_%, aq$_%, etc.) so that has_schema_privilege evaluates them as physical schemas without crashing.
Environment:
- PostgreSQL version: EDB Postgres Advanced Server (EPAS) 15.15, 17.9, 18.1
- ldap2pg version: 6.5.1
- OS: Kubernetes / CloudNativePG
Thank you for this amazing tool, hoping this edge-case can be fixed in a future release!
Zoli
- Dominant language
- Go
- Stars
- 241
- Forks
- 38
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 2
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dalibo/ldap2pg
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 4/5 3-5 days Newbie friendliness 54/100
-
Difficulty 3/5 1-2 days Newbie friendliness 72/100
Similar issues
-
agent-butler-finding chore
Difficulty 1/5 Under an hour Newbie friendliness 78/100
jordansmall/spindrift#6318 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Eyevinn/moqlivemock#166 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
JakeChampion/lang#14091 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
hyperledger/fabric-x-orderer#1409 ·
Maintainers usually reply within 3 days
-
get actions doesn't show the approval flag, and describe action shows it unformattedPossibly taken @kenokech claimed this today. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day