DETAIL: Detail redacted as it may contain sensitive data. Specify 'Include Error Detail' in the connection string to include this information. is not an error of its own. It is Npgsql hiding the DETAIL line of a PostgreSQL error; the real error is the line above it. To see the detail, add Include Error Detail=true to the connection string, in development only.

The setting changes nothing else: the same exception is thrown, now with the server's DETAIL text, which for a unique violation names the duplicate value and for a NOT NULL violation prints the whole row. That is exactly why it is off by default.

The error

Unhandled exception. Npgsql.PostgresException (0x80004005): 23505: duplicate key value violates unique constraint "customers_email_key"

DETAIL: Detail redacted as it may contain sensitive data. Specify 'Include Error Detail' in the connection string to include this information.

A NOT NULL violation, 23502: null value in column "full_name" of relation "customers" violates not-null constraint, came with the same redacted DETAIL line.

Why it happens

PostgreSQL sends a DETAIL field with many errors. Npgsql reads it and, unless the connection string enables Include Error Detail, replaces it with the sentence above before it builds the PostgresException; the replacement is in Npgsql's ErrorOrNoticeMessage.cs. The connection string reference lists the option with a default of false and warns that the details can contain sensitive data. Exception text travels into log files, error pages and telemetry, and a DETAIL can hold an email address, a name or whatever else the failing row contains, so the safe default is to leave it out.

Only the DETAIL is removed. SqlState, TableName and ConstraintName (or ColumnName for 23502) stayed filled in, so code can still tell which rule failed. The PostgreSQL server log of the test container recorded the full DETAIL for every run, redacted on the client or not.

The fix

var connectionString = "Host=127.0.0.1;Port=15470;Database=shop;Username=postgres;Password=lab-only-pass";
if (args.Contains("--detail"))
    connectionString += ";Include Error Detail=true";

The lab turns it on with a command-line switch. With it, the same two inserts reported:

Unhandled exception. Npgsql.PostgresException (0x80004005): 23505: duplicate key value violates unique constraint "customers_email_key"

DETAIL: Key (email)=(maria.garcia@example.test) already exists.

Unhandled exception. Npgsql.PostgresException (0x80004005): 23502: null value in column "full_name" of relation "customers" violates not-null constraint

DETAIL: Failing row contains (2, david.chen@example.test, null).

If you build connection strings in code, the builder property does the same; this run printed the same unique-violation DETAIL:

var csb = new NpgsqlConnectionStringBuilder(connectionString) { IncludeErrorDetail = true };
connectionString = csb.ConnectionString;

Keep the option out of the production connection string, for example by adding it only in appsettings.Development.json or user secrets. In production, branch on SqlState and ConstraintName instead. With EF Core, EnableSensitiveDataLogging does not lift the redaction: the inner PostgresException stayed redacted until the connection string had the option.

How it was reproduced

A dotnet new console app with Npgsql 10.0.3 against PostgreSQL 18.4 in the postgres:18 Docker image on 127.0.0.1:15470. A customers table with a unique email and a NOT NULL full_name, one seeded row, then a duplicate email insert and a NULL name insert, each with and without the option. A second app with EF Core 10.0.4 and Npgsql.EntityFrameworkCore.PostgreSQL 10.0.3 checked EnableSensitiveDataLogging. .NET SDK 10.0.402 on Windows 11; names and emails are fictional.

Frequently asked

How do I see the redacted detail of a Npgsql PostgresException?
Add Include Error Detail=true to the connection string, or set IncludeErrorDetail = true on an NpgsqlConnectionStringBuilder, and run again. The DETAIL line of the exception and PostgresException.Detail then carry the text PostgreSQL sent, such as Key (email)=(...) already exists.
Does EF Core EnableSensitiveDataLogging show the Npgsql error detail?
No. With EF Core 10.0.4 and Npgsql.EntityFrameworkCore.PostgreSQL 10.0.3 the inner PostgresException was still redacted with sensitive data logging on. Only the Include Error Detail connection string option showed it.
Is it safe to turn on Include Error Detail in production?
The Npgsql documentation keeps it off by default because the details can contain sensitive data, and a NOT NULL violation printed the whole failing row. Use it in development; in production branch on SqlState and ConstraintName, which stay available.

More decoded errors in the Fixes category. If the redacted line sits under a duplicate primary key right after seeding, see 23505 after seeding rows.