ERROR: Listing secrets of "https://vault.local:8200" at mountpoint "pg-tde" failed

Greetings!

I have been following the instructions listed in Configure pg_tde and Vault Configuration to get my PostgreSQL 17 database encrypted using the Percona pg_tde extension. However, for some reason I’m unable to add my self-hosted HashiCorp Vault as a global vault provider.

The main issue I’m currently facing comes from the method pg_tde_add_global_key_provider_vault_v2

psql list function

\df
public | pg_tde_add_global_key_provider_vault_v2 | integer | provider_name text, vault_token text, vault_url text, vault_mount_path text, vault_ca_path text | func

psql use the function

SELECT pg_tde_add_global_key_provider_vault_v2('vault-local','/vault/token','https://vault.local:8200','pg-tde','/etc/ssl/psql/ca.crt');
ERROR:  Listing secrets of "https://vault.local:8200" at mountpoint "pg-tde" failed

/vault/config/vault.hcl

ui = true
disable_mlock = true
log_level = "info"

storage "file" {
  path = "/vault/data"
}

listener "tcp" {
  address = "0.0.0.0:8200"
  http_idle_timeout = "5m"
  tls_disable = "false"
  tls_cert_file = "/etc/ssl/vault/server.crt"
  tls_key_file = "/etc/ssl/vault/server.key"
  tls_min_version = "tls13"
  tls_max_version = "tls13"
  tls_require_and_verify_client_cert = "false"
  tls_client_ca_file = "/etc/ssl/ca.crt"
  tls_disable_client_certs = "false"
}

AppRole for pg_tde

vault write auth/approle/role/pg-tde \
  token_policies="pg-tde-policy" \
  token_ttl=60m \
  token_max_ttl=120m \
  role_id=postgres-pg-tde

pg-tde-policy.hcl

# development policies for pg_tde in postgres

path "pg-tde/*" {
  capabilities = ["read", "create", "update", "patch", "delete", "list"]
}

path "pg-tde/data/*" {
  capabilities = ["read", "create", "update", "patch", "delete", "list"]
}

path "pg-tde/metadata/*" {
  capabilities = ["read", "create", "update", "patch", "delete", "list"]
}

Testing the Vault configuration with vault cli from postgres

export environment variables

$ export VAULT_ADDR=https://vault.local:8200
$ export VAULT_CACERT=/etc/ssl/psql/ca.crt
$ export VAULT_TOKEN=$(cat /vault/token)

secrets list

$ vault secrets list
Path                      Type         Accessor              Description
----                      ----         --------              -----------
pg-tde/                   kv           kv_4ae22c7c           n/a

list secrets in pg-tde

$ vault list pg-tde/metadata
No value found at pg-tde/metadata

put secret in pg-tde

$ vault kv put pg-tde/pg_tde_key key=$(openssl rand 32 | base64)
============ Secret Path ============
pg-tde/data/pg_tde_key

======= Metadata =======
Key                Value
---                -----
created_time       2025-07-16T07:08:15.770953098Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

get secret from pg-tde

$ vault kv get pg-tde/pg_tde_key
============ Secret Path ============
pg-tde/data/pg_tde_key

======= Metadata =======
Key                Value
---                -----
created_time       2025-07-16T07:08:15.770953098Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

=== Data ===
Key    Value
---    -----
key    M1Fk852AaEugt0obBjgopR/eFzqGoaCqUznCKZ7yvLs=

Based on the following configuration and tests listed, I would assume my self-hosted Vault is properly configured for providing an accessible KV secrets engine for pg_tde. What would be the issue for the error message I’m receiving?

Dear User,

Thank you for reaching out.

Based on the latest pg_tde documentation, it appears that the issue stems from the order of arguments provided to the pg_tde_add_global_key_provider_vault_v2 function.

The correct syntax is:

SELECT pg_tde_add_global_key_provider_vault_v2(
‘provider-name’,
‘url’,
‘mount’,
‘secret_token_path’,
‘ca_path’
);

In your example, the arguments were passed in an incorrect order, which is why the function failed to access the Vault mount point.

Please correct the argument order and try again. Let us know if you encounter any further issues.

Best regards,
Mohit J

Hi, thanks for replying.

Unfortunately that didn’t resolve my issue. In my original post I mentioned the psql list function to show what the command \df outputs for the function’s parameter order in my psql instance.

I tried to run the following order of parameters you and the original documentation for Vault Configuration mentions and got a different error which seems to imply that the HTTPS request simply fails.

psql

SELECT pg_tde_add_global_key_provider_vault_v2('vault-local','https://vault.local:8200','pg-tde','/vault/token','/etc/ssl/psql/ca.crt');
ERROR:  HTTP(S) request to keyring provider "vault-local" failed

For added context, I’ve installed the latest release of Percona pg_tde extension in my PostgreSQL instance running on Docker.

Percona PostgreSQL install

# Remove original PostgreSQL packages to avoid conflicts
RUN apt-get remove -y postgresql-client postgresql-client-common postgresql-common postgresql-common-dev

# Get and enable the use of latest Percona PostgreSQL release
RUN curl -O https://repo.percona.com/apt/percona-release_latest.generic_all.deb
RUN dpkg -i percona-release_latest.generic_all.deb && \
    percona-release enable ppg-17.5

# Install percona-postgresql-17
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    percona-postgresql-17 && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

PostgreSQL configuration for shared_preload_libraries

shared_preload_libraries = 'pg_tde'

PostgreSQL init pg_tde extension

-- Enable Percona PostgreSQL pg_tde extension for data encryption
CREATE EXTENSION IF NOT EXISTS pg_tde;

Also regarding if the installed pg_tde extension works at all, I’ve managed to get it working using a Keyring File Configuration.

BR,
TW

Update:

The core issue was with my install operation. After carefully following the instructions on Installing pg_tde with apt. I noticed, that I had used percona-release enable instead of percona-release enable-only in my Dockerfile. After rebuilding the image, I managed to get my vault provider properly added in psql with the parameter order mentioned in the Documentation.

BR,
TW

1 Like

Glad that you were able to figure out. Happy to help!
With the latest installation you must see

select version();
version

PostgreSQL 17.5 - Percona Server for PostgreSQL 17.5.2 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, 64-bit
(1 row)

\df pg_tde_add_database_key_provider_vault_v2
List of functions
Schema | Name | Result data type | Argument data types | Type
--------±------------------------------------------±-----------------±-----------------------------------------------------------------------------------------------------±-----
public | pg_tde_add_database_key_provider_vault_v2 | void | provider_name text, vault_url text, vault_mount_path text, vault_token_path text, vault_ca_path text | func
(1 row)