MySQL
error handling
database troubleshooting
SQL commands
technical issue

Commands out of sync; you can't run this command now

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The MySQL error Commands out of sync; you can't run this command now means the client tried to send a new command before it had fully finished the previous one. This is not usually a server bug. It is almost always a client-side sequencing problem involving unread result sets, stored procedures that return multiple results, or code that reuses one connection too aggressively.

What “Out of Sync” Actually Means

A MySQL connection is a conversation between the client library and the server. That conversation has a strict order:

  1. send a query
  2. consume or discard the result
  3. send the next query

If step 2 is incomplete, the client library is still busy with the old response when your code tries to start the next command. That is when the “out of sync” error appears.

This is especially common with:

  • 'mysql_use_result() when rows are not fully consumed'
  • stored procedures that emit multiple result sets
  • APIs that require nextset() or equivalent cleanup
  • code that mixes reads and writes on one connection without finishing cursors

C API Example of the Problem

With the MySQL C API, a common mistake is forgetting to free or fully consume the result:

c
1#include <mysql/mysql.h>
2#include <stdio.h>
3
4int main(void) {
5    MYSQL *conn = mysql_init(NULL);
6    mysql_real_connect(conn, "127.0.0.1", "root", "secret", "demo", 0, NULL, 0);
7
8    mysql_query(conn, "SELECT id FROM users");
9    MYSQL_RES *result = mysql_store_result(conn);
10
11    /* wrong: issuing a new command before cleaning up result properly */
12    /* mysql_query(conn, "SELECT COUNT(*) FROM users"); */
13
14    mysql_free_result(result);
15    mysql_query(conn, "SELECT COUNT(*) FROM users");
16
17    mysql_close(conn);
18    return 0;
19}

The fix is simple: always free the result from the first command before sending the second command.

Stored Procedures and Multiple Result Sets

Stored procedures make this error more common because one call may produce more than one result set. Even if you only care about the first result, the connection must still be advanced through the rest.

In the C API, the cleanup loop often looks like this:

c
1mysql_query(conn, "CALL get_user_and_stats()");
2
3do {
4    MYSQL_RES *result = mysql_store_result(conn);
5    if (result != NULL) {
6        mysql_free_result(result);
7    }
8} while (mysql_next_result(conn) == 0);

That loop matters because CALL can leave additional result packets waiting. If you skip them, the next query can fail with the out-of-sync error.

Driver-Level Examples in Higher-Level Languages

Higher-level drivers have the same rule even if the API is friendlier.

In Python with mysqlclient or PyMySQL, you usually need to fetch the rows or close the cursor before reusing the connection:

python
1import pymysql
2
3conn = pymysql.connect(host="127.0.0.1", user="root", password="secret", database="demo")
4
5with conn.cursor() as cur:
6    cur.execute("SELECT id FROM users")
7    rows = cur.fetchall()
8    print(rows)
9
10with conn.cursor() as cur:
11    cur.execute("SELECT COUNT(*) FROM users")
12    print(cur.fetchone())
13
14conn.close()

The important part is finishing the first cursor before starting the second command on the same connection.

mysql_use_result() Requires Full Consumption

mysql_use_result() streams rows instead of buffering them all at once. That can save memory, but it means you must read every row before using the connection again.

If you do this:

c
1MYSQL_RES *result = mysql_use_result(conn);
2MYSQL_ROW row = mysql_fetch_row(result);
3/* stop early here */
4mysql_query(conn, "SELECT 1");

you are almost guaranteed to trigger the error, because unread rows are still pending on the connection.

If you need simpler control flow, mysql_store_result() is often easier because it buffers the result and lets you free it explicitly.

One Connection Is Not Parallel

Another common cause is trying to treat one MySQL connection as if it can run two commands at once. It cannot, unless you are deliberately using a supported multi-query or asynchronous API and consuming all results correctly.

If you need parallel work, use separate connections. That is cleaner and much easier to reason about.

This comes up in web applications when one request handler holds an open cursor and another part of the code tries to reuse the same shared connection immediately.

A Debugging Checklist

When you see this error, ask these questions:

  • Did I fetch or free the previous result completely?
  • Did the previous statement return multiple result sets?
  • Am I reusing a connection while a cursor is still active?
  • Did I use a streaming API such as mysql_use_result() and stop early?

In most cases, the answer is one of those four.

Common Pitfalls

The biggest pitfall is assuming that ignoring the rest of a result set is harmless. It is not. The connection still has unread data.

Another issue is forgetting that stored procedures can emit multiple results even when your SQL text looks like one call.

Shared-connection designs also cause trouble. A single connection is sequential, not concurrent.

Finally, switching from one client library to another does not remove the rule. The method names change, but the protocol constraint stays the same.

Summary

  • The error means a new MySQL command was sent before the previous result was fully handled.
  • Always fetch or free result sets before reusing the connection.
  • Stored procedures may require nextset() or equivalent result-draining logic.
  • Streaming results with mysql_use_result() require full consumption before the next command.
  • If you need parallel database work, use separate connections rather than one shared connection.

Course illustration
Course illustration

All Rights Reserved.