Troubleshoot the DuckDB plugin
Plugin does not load
cannot open shared object file
Confirm the plugins entry uses the installed absolute path and that the
ProxySQL service account can read the .so and traverse its parent directories.
Check the loader error for any missing shared-library dependency too.
ABI or DEBUG mismatch
Install a core and plugin built together with the same tier and build mode.
A DEBUG core requires a DEBUG plugin; release requires release. When rebuilding,
clean stale objects after changing modes and use PROXYSQL40=1 on every build
invocation. Follow the Installation guide.
DuckDB source archive fails verification during build
From the ProxySQL source root, run:
bash deps/duckdb/verify-source.bash
Inspect the checksum or corrupt-archive diagnostic. If the vendored archive is missing or damaged, restore it from the matching source checkout before rebuilding.
Engine fails to open
File or directory permission error
Check duckdb-database_path, parent-directory existence, ownership, service
sandbox rules, and permissions for the ProxySQL operating-system account.
Writable databases need write access to their containing directory as well as
the database file. Use an absolute path to avoid opening a different file when
the service’s working directory changes.
Read-only in-memory configuration
duckdb-read_only=true cannot use :memory: or an empty database path. Configure
an existing file-backed database or disable read-only mode, save the corrected
configuration, and restart ProxySQL.
Invalid memory limit or engine setting
Inspect the startup log for the setting named in a duckdb_set_config error or
the database-open error. Correct the saved value before restarting again.
For a running plugin, LOAD validates duckdb-memory_limit before applying live
changes.
Listener does not start
Check whether the configured address exists locally and whether another process or ProxySQL listener is using the port. Use a dedicated port for each listener. Common defaults are:
- 6031: DuckDB MySQL protocol
- 6032: ProxySQL Admin
- 6033: normal ProxySQL MySQL listener
- 6034: DuckDB PostgreSQL protocol
An empty listener value disables that protocol. After changing
duckdb-mysql_ifaces or duckdb-pgsql_ifaces, save to Disk and restart ProxySQL.
LOAD does not rebind sockets.
Authentication fails
Use a frontend credential in the correct table:
- MySQL endpoint:
mysql_users - PostgreSQL endpoint:
pgsql_users
Confirm the user is active, enabled for frontend use, and loaded to Runtime.
Use LOAD MYSQL USERS TO RUNTIME or LOAD PGSQL USERS TO RUNTIME after editing
the corresponding table, and save users to Disk if they must survive restart.
A user needs a corresponding entry in each table to authenticate through both
protocols. See the Quickstart for examples.
Connection resets immediately
Check duckdb-max_connections and application connection-pool sizes. At the
cap, the plugin closes new sockets before protocol setup, so clients may show
EOF or a reset instead of a descriptive error. Lowering the cap preserves
existing connections.
If connections stall during authentication, check the ProxySQL log for a
Closing not established DuckDB client connection warning and review
mysql-connect_timeout_client or pgsql-connect_timeout_client for that
endpoint. Also check for startup or shutdown activity.
Query syntax works in MySQL or PostgreSQL but fails here
The endpoint protocol does not select the SQL dialect. Write DuckDB SQL. Only a small set of discovery and session commands is handled for compatibility.
Start with:
SELECT 42;
Then reduce the failing statement to identify unsupported syntax, missing objects, permissions, or a driver protocol mode. See Protocol compatibility.
Prepared statement or parameterized query fails
The listeners do not support client-visible prepared statements. MySQL clients
receive Command not supported (error 1045, SQLSTATE 28000) when preparing a
statement, even after successful authentication. PostgreSQL extended-query
requests return SQLSTATE 0A000.
Configure the driver for simple-query mode or use a non-prepared text-query API. Check that the driver’s parameter API can safely encode values in that mode; do not concatenate untrusted input into SQL. If the driver requires server-side prepared statements, choose another compatible client or access method.
Multiple SQL statements are rejected
Send one statement per request. For example, send SET NAMES utf8 and
SELECT 1 separately; sending SET NAMES utf8; SELECT 1 as one request is
rejected. Check driver connection initialization settings for batches of SQL
statements.
Values arrive as strings
Both protocols advertise text columns. Parse results according to the expected query schema instead of relying on MySQL or PostgreSQL numeric or date type metadata. Set explicit result-conversion rules in your application where the driver permits them.
A special DuckDB value arrives as NULL
Some result types, such as UUIDs and nested values, need conversion to text.
For ordinary queries the plugin normally performs this conversion. Certain
statements, including DML with RETURNING, cannot use that conversion and may
return NULL for an unsupported type even when the stored value is not NULL.
Cast the affected expression explicitly in the original statement. For
example, if items.id is a UUID:
INSERT INTO items (id) VALUES (UUID()) RETURNING id::VARCHAR;
Configuration changed but behavior did not
Compare the editable and running values through ProxySQL Admin:
SELECT variable_name, variable_value FROM global_variables
WHERE variable_name LIKE 'duckdb-%' ORDER BY variable_name;
SELECT variable_name, variable_value FROM runtime_global_variables
WHERE variable_name LIKE 'duckdb-%' ORDER BY variable_name;
For a live change, run LOAD DUCKDB VARIABLES TO RUNTIME and inspect any error.
An invalid value or pending restart change in Main causes the request to fail,
including other valid live edits. Correct those values before retrying.
For listener addresses, database path, read-only mode, or enabling external
access, save Main with SAVE DUCKDB VARIABLES TO DISK and restart ProxySQL.
Runtime shows what is in effect until then. See the
Admin reference.
Configuration disappears after restart
LOAD applies changes without saving them. After reviewing Main, persist it:
SAVE DUCKDB VARIABLES TO DISK;
Verify the saved duckdb-* rows in disk.global_variables. Saving Runtime to
Memory first will replace Main and discard any pending edits, so use that
command only if the running settings are the ones you intend to keep.
External file access is denied
External access is disabled by default. Review the
Security guide before enabling it. To enable
it deliberately, edit duckdb-enable_external_access in Main, save to Disk,
and restart ProxySQL. LOAD cannot enable it while the database is open.
Also verify the ProxySQL account’s filesystem permissions and any service
sandbox restrictions.
A query consumes excessive resources
The plugin has no per-query execution timeout. Bound application concurrency,
review duckdb-memory_limit, choose a conservative duckdb-threads value, and
reduce duckdb-max_connections as needed; all three settings apply live.
The memory limit is not a cap on total process memory, and reducing the
connection limit does not stop existing sessions or queries.
If a running query must stop and the client cannot cancel it, a controlled ProxySQL restart may be necessary. Include normal ProxySQL traffic in that recovery plan. A restart loses in-memory DuckDB data and interrupts active work.