jackc/pgx · error
simple protocol queries must be run with client_encoding=UTF
Error message
simple protocol queries must be run with client_encoding=UTF8
What it means
Returned by sanitizeForSimpleQuery when the session's client_encoding is not 'UTF8'. Client-side SQL sanitization (simple protocol) assumes UTF-8 so byte-level escaping of string literals is correct; any other encoding could mis-escape and produce malformed or injectable SQL. pgx refuses rather than guess.
Source
Thrown at conn.go:1270
if err != nil {
return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}
}
return &pipelineBatchResults{
ctx: ctx,
conn: c,
pipeline: pipeline,
b: b,
}
}
func (c *Conn) sanitizeForSimpleQuery(sql string, args ...any) (string, error) {
if c.pgConn.ParameterStatus("standard_conforming_strings") != "on" {
return "", errors.New("simple protocol queries must be run with standard_conforming_strings=on")
}
if c.pgConn.ParameterStatus("client_encoding") != "UTF8" {
return "", errors.New("simple protocol queries must be run with client_encoding=UTF8")
}
var err error
valueArgs := make([]any, len(args))
for i, a := range args {
valueArgs[i], err = convertSimpleArgument(c.typeMap, a)
if err != nil {
return "", err
}
}
return sanitize.SanitizeSQL(sql, valueArgs...)
}
// LoadType inspects the database for typeName and produces a [pgtype.Type] suitable for registration. typeName must be
// the name of a type where the underlying type(s) is already understood by pgx. It is for derived types. In particular,
// typeName must be one of the following:
// - An array type name of a type that is already registered. e.g. "_foo" when "foo" is registered.View on GitHub (pinned to ec1a0befd2)
Solutions
- Remove any SET client_encoding=... that moves away from UTF8; let it default to UTF8.
- Set the server default client_encoding to UTF8 in postgresql.conf.
- Switch DefaultQueryExecMode to an extended-protocol mode so pgx binds parameters binary-wise and encoding of literal text no longer matters to sanitization.
- After connect, verify SHOW client_encoding returns UTF8 and fail fast otherwise.
Example fix
// before config.DefaultQueryExecMode = pgx.QueryExecModeExec // session has SET client_encoding='LATIN1' // after config.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement // and ensure client_encoding stays UTF8
Defensive patterns
Strategy: validation
Validate before calling
var ce string
if err := conn.QueryRow(ctx, "SHOW client_encoding").Scan(&ce); err != nil { return err }
if ce != "UTF8" { return fmt.Errorf("refusing simple-protocol: client_encoding=%q", ce) } Type guard
func utf8ForSimpleProtocol(c *pgx.Conn) bool {
return c.PgConn().ParameterStatus("client_encoding") == "UTF8"
} Try / catch
if err != nil && strings.Contains(err.Error(), "client_encoding=UTF8") {
cfg.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement // bypass sanitization
} Prevention
- Keep client_encoding at UTF8 server-wide.
- Avoid SET client_encoding=... to regional encodings.
- Use extended-protocol modes so sanitization is not involved.
When it happens
Trigger: Running simple-protocol queries against a session whose client_encoding GUC has been changed away from UTF8 (e.g. SET client_encoding='LATIN1'; or a server/pooler that negotiates a non-UTF8 client encoding).
Common situations: A legacy database or middleware that sets client_encoding to a regional encoding (LATIN1, SQL_ASCII, WIN1252); a connection pooler that injects encoding setup; restoring a dump that ran SET client_encoding.
Related errors
- simple protocol queries must be run with standard_conforming
- secret key too long
- too many column format codes
- too many column format codes
- too many column format codes
AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04).
Data as JSON: /data/errors/ac723f17698550bc.json.
Report an issue: GitHub.