Skip to content

58P02 — duplicate_file

Source-backed reference for PostgreSQL SQLSTATE 58P02.

58P02

At a glance

58P02 is the duplicate-file condition in the fixed server-side base-backup output path. The path accepts a missing directory, accepts an existing empty directory, and raises this code when the existing target is non-empty.

Field Value
SQLSTATE 58P02
Condition duplicate_file
Status active
Known present by 7.4
Locked snapshots 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3
Macros ERRCODE_DUPLICATE_FILE
Aliases

Meaning

bbsink_server_new() first performs and commits its privilege check transaction. It then rejects relative paths and calls pg_check_dir(pathname): result 0 creates the directory, result 1 accepts an empty directory, and results 2–4 enter the fixed ERRCODE_DUPLICATE_FILE branch. An access error takes a separate errcode_for_file_access() branch. This is a base-backup output safety check, not proof that every EEXIST or non-empty directory in PostgreSQL uses 58P02.

Messages

  • ERROR, SQLSTATE 58P02: directory "%s" exists but is not empty.
  • ERROR, with errcode_for_file_access(): could not access directory "%s": %m.
  • ERROR, with errcode_for_file_access(): could not create directory "%s": %m when the target is absent but creation fails.

The last two templates receive their SQLSTATE from the saved OS errno and should not be relabeled 58P02 merely because they occur in the same function.

Diagnosis

Confirm that the path is the intended base-backup destination, inspect its owner, mount, and inventory, and determine whether it contains a prior complete backup or an interrupted one. Preserve that inventory before changing it. The source path performs output preparation after the internal privilege-check transaction has been committed, so this condition is a failed backup setup rather than evidence that a user DML transaction can be repaired by blindly continuing.

Response

Use a documented empty destination or archive the previous output according to the backup policy. Validate the completed backup and its manifest after creation; never recursively delete or force-overwrite an unknown directory. If an outer client command reports an ERROR, follow the actual session state and roll back to an existing savepoint or transaction as appropriate, but do not treat ROLLBACK as a way to make the non-empty backup target safe. A new connection is needed only if the owning server process was terminated.

Versions

The locked catalogue records this condition from 7.4; the fixed base-backup path is from PostgreSQL 18.6. No backup target was altered or tested for this source-only entry.

58P01, 58P03, 53100

Sources

src/backend/backup/basebackup_server.c#L59-L125

The structured evidence record records the directory-state branches, dynamic errno paths, and source/runtime boundary.