Skip to content

When something is refused

Two things happen when the extension refuses an operation.


1. You get an error

The error says what was refused and why:

ERROR:  update is not permitted on vault table "audit_log"
DETAIL:  The table's permissions are "insert".
HINT:   A vault table's permissions are fixed at creation and cannot be altered.

The DETAIL line tells you what the table actually allows, which is usually the fastest way to work out whether the table is wrong or your expectation is.

Because it is a normal PostgreSQL error, it aborts the transaction like any other. Nothing is half-done.


2. A record goes into the server log

At the same time, a line is written to the PostgreSQL log:

pg_vault_tables_violation: ts=2026-08-17 09:14:22+10 operation=update
  reason=not_permitted database=prod schema=public table=audit_log
  permissions=insert retention_days= current_user=alice session_user=bob
  client_addr=10.1.2.3 application_name=psql pid=8210

You will not normally see this yourself — it is in the server log, which your DBA can read. That is the point. A refused attempt is worth somebody knowing about, and it would be worth very little if the only person who ever saw it was the person who made the attempt.

Notice current_user and session_user are both recorded. They differ when somebody has used SET ROLE, and that difference matters when working out what happened.


What counts as a violation

Two kinds of thing:

  • An operation the table does not grant — an update on an append-only table, a drop on a table without drop, any ALTER TABLE at all.
  • Deleting a row before its retention deadline.

Normal work produces nothing. A permitted insert writes no record; neither does a purge that removes eligible rows. So anything appearing in the log is genuinely unusual.


The most common messages

Message What it means
update is not permitted on vault table "x" The table does not grant update. Check the DETAIL line for what it does grant.
row in vault table "x" is still within its retention period The row has not reached its deadline. Use WHERE _$purge_ts < now(), or wait.
ALTER TABLE is not permitted on vault table "x" The form attempted is one no permission grants, such as DROP COLUMN or SET ACCESS METHOD.
adding a column is not permitted on vault table "x" The table does not grant addcolumn.
changing trigger state / row level security / policies / logged or unlogged / tablespace is not permitted The table does not grant trigger / rls / policy / log / tablespace.
changing a column default is not permitted on vault table "x" The table does not grant coldefault.
column "c" is not updatable on vault table "x" The table's update grant names the columns it may change, and this is not one of them. The DETAIL line lists the ones that are.
a vault table may not declare a column named "_$purge_ts" That name is reserved for the retention deadline. Set retention and it is created for you; choose another name for a column of your own.
direct catalogue modification of a vault table is not permitted Something wrote a system catalogue in a way that changed a vault table's declaration. Rows belonging to other objects are unaffected.
storage parameters cannot be changed on vault table "x" Set them in CREATE TABLE instead; they cannot be altered afterwards. Column-level settings are unaffected.
vault table "x" already holds its one permitted insert The table grants insertonce and has already been used.
drop is not permitted on vault table "x" The table does not grant drop, so it cannot be removed.