{"id":"0aa5700625e9538d","repo":"jackc/pgx","slug":"simple-protocol-queries-must-be-run-with-standard","errorCode":null,"errorMessage":"simple protocol queries must be run with standard_conforming_strings=on","messagePattern":"simple protocol queries must be run with standard_conforming_strings=on","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"conn.go","lineNumber":1266,"sourceCode":"\t\t}\n\t}\n\n\terr := pipeline.Sync()\n\tif err != nil {\n\t\treturn &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true}\n\t}\n\n\treturn &pipelineBatchResults{\n\t\tctx:      ctx,\n\t\tconn:     c,\n\t\tpipeline: pipeline,\n\t\tb:        b,\n\t}\n}\n\nfunc (c *Conn) sanitizeForSimpleQuery(sql string, args ...any) (string, error) {\n\tif c.pgConn.ParameterStatus(\"standard_conforming_strings\") != \"on\" {\n\t\treturn \"\", errors.New(\"simple protocol queries must be run with standard_conforming_strings=on\")\n\t}\n\n\tif c.pgConn.ParameterStatus(\"client_encoding\") != \"UTF8\" {\n\t\treturn \"\", errors.New(\"simple protocol queries must be run with client_encoding=UTF8\")\n\t}\n\n\tvar err error\n\tvalueArgs := make([]any, len(args))\n\tfor i, a := range args {\n\t\tvalueArgs[i], err = convertSimpleArgument(c.typeMap, a)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\n\treturn sanitize.SanitizeSQL(sql, valueArgs...)\n}\n","sourceCodeStart":1248,"sourceCodeEnd":1284,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/conn.go#L1248-L1284","documentation":"Returned by (*Conn).sanitizeForSimpleQuery before client-side parameter interpolation when the server's standard_conforming_strings GUC is not 'on'. pgx only sanitizes simple-protocol queries when backslash escapes are disabled (standard_conforming_strings=on), because off-mode would let backslashes change string semantics and break the escaping logic — a potential SQL-injection vector. The guard is defensive; PostgreSQL has defaulted this to on since 9.1.","triggerScenarios":"Executing a query in QueryExecModeExec (simple protocol) — or otherwise hitting sanitizeForSimpleQuery (conn.go:586/863/1027/1264) — against a server or session where standard_conforming_strings is off, e.g. set explicitly via SET standard_conforming_strings=off; or a legacy/old cluster.","commonSituations":"A migration or DBA script that issues SET standard_conforming_strings=off for backward compatibility; an inherited PostgreSQL 8.x/9.0 era cluster config; a pooler that reconfigures session GUCs; a test database with legacy settings.","solutions":["Ensure the server/cluster default is standard_conforming_strings=on (it has been since PG 9.1) and remove any SET standard_conforming_strings=off.","Switch the connection's DefaultQueryExecMode away from QueryExecModeExec (simple protocol) to an extended-protocol mode (CacheStatement/CacheDescribe/DescribeExec/Exec), which binds parameters safely without sanitization.","After connecting, run SHOW standard_conforming_strings and fail fast if it is not 'on' so misconfigured sessions are caught early.","If a legacy app needs off-mode, separate that workload onto its own connection with extended-protocol mode."],"exampleFix":"// before\nconfig.DefaultQueryExecMode = pgx.QueryExecModeExec // simple protocol\n\n// after — use extended protocol (default), bypassing sanitization\nconfig.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement","handlingStrategy":"validation","validationCode":"var scs string\nif err := conn.QueryRow(ctx, \"SHOW standard_conforming_strings\").Scan(&scs); err != nil { return err }\nif scs != \"on\" { return fmt.Errorf(\"refusing simple-protocol: standard_conforming_strings=%q\", scs) }","typeGuard":"func safeForSimpleProtocol(c *pgx.Conn) bool {\n    return c.PgConn().ParameterStatus(\"standard_conforming_strings\") == \"on\"\n}","tryCatchPattern":"_, err := conn.Exec(ctx, sql, args...)\nif err != nil && strings.Contains(err.Error(), \"standard_conforming_strings=on\") {\n    // switch off simple protocol or fix the GUC\n    cfg.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement\n}","preventionTips":["Prefer extended-protocol modes (default) over QueryExecModeExec.","Do not issue SET standard_conforming_strings=off.","Verify the GUC at startup and fail fast if off."],"tags":["simple-protocol","security","guc","sanitization"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}