How to Fix MySQL Error 1058: Column Count Doesn't Match Value Count

ERROR 1058 (21S01): Column count doesn't match value count is raised when an INSERT statement specifies a column list and a VALUES clause that contain a different number of entries. The error symbol is ER_WRONG_VALUE_COUNT.

Impact

The INSERT statement is rejected immediately and no rows are written. The query returns an error to the client before any data modification occurs, so there is no partial insert to roll back. Because the error happens at parse/validation time, it fires consistently — every execution of the same malformed statement will fail.

Developers typically encounter this when writing INSERT statements by hand, when generating SQL dynamically (where column or value lists are built in separate code paths), or after altering a table and not updating the corresponding query. ORMs that produce raw SQL (e.g., Sequelize with a literal query, JOOQ's plain SQL API, or SQLAlchemy's text()) will surface this as a database-level exception rather than a framework-level validation error, so the root cause is always the SQL itself.

Common Causes

  1. Explicit column list has more or fewer entries than the VALUES list. The most common trigger — a column was added to one side of the statement but not the other.

  2. Multi-row INSERT with an inconsistent row in VALUES. When inserting multiple rows with VALUES (...), (...), (...), each row tuple must have the same number of values as the column list. A single short or long tuple fails the whole statement.

  3. Dynamically built SQL where column and value arrays get out of sync. Application code that constructs the column list and value placeholders in separate loops can produce a mismatch if a conditional adds a column but skips the corresponding placeholder (or vice versa).

  4. Copy-pasted INSERT where the table was later altered. A working statement saved in a script or migration file can break when a column is added or removed from the table and only one side of the INSERT is updated.

  5. Omitting the column list when the value count doesn't match the full table schema. If the column list is omitted entirely, MySQL expects one value for every column in the table. Providing fewer values raises error 1058.

Troubleshooting and Resolution Steps

  1. Count columns and values side by side. Read the failing statement and count each list explicitly:

    -- Broken: 3 columns, 2 values
    INSERT INTO orders (customer_id, product_id, quantity)
    VALUES (42, 17);
    
    -- Fixed: counts match
    INSERT INTO orders (customer_id, product_id, quantity)
    VALUES (42, 17, 3);
    
  2. Check the table structure to understand required columns.

    DESCRIBE orders;
    -- or
    SHOW COLUMNS FROM orders;
    

    This reveals the full column list so you can decide whether to include a column in the INSERT or rely on its default value.

  3. For multi-row inserts, verify every row tuple has the same count.

    -- Broken: second row has only 2 values
    INSERT INTO orders (customer_id, product_id, quantity)
    VALUES (42, 17, 3),
           (55, 9);      -- missing quantity
    
    -- Fixed
    INSERT INTO orders (customer_id, product_id, quantity)
    VALUES (42, 17, 3),
           (55, 9, 1);
    
  4. When no column list is provided, supply a value for every column.

    -- Table has 4 columns: id (AUTO_INCREMENT), customer_id, product_id, quantity
    -- Broken: only 3 values provided
    INSERT INTO orders VALUES (42, 17, 3);
    
    -- Fixed: include all 4, or use NULL/DEFAULT for auto-increment
    INSERT INTO orders VALUES (DEFAULT, 42, 17, 3);
    

    Prefer specifying an explicit column list to avoid fragile position-dependent inserts.

  5. In application code, build the column and value arrays from the same source. If your code constructs both lists, derive them from a single map or dictionary so they can never diverge:

    # Python example — derive both lists from one dict
    row = {"customer_id": 42, "product_id": 17, "quantity": 3}
    columns = ", ".join(row.keys())
    placeholders = ", ".join(["%s"] * len(row))
    sql = f"INSERT INTO orders ({columns}) VALUES ({placeholders})"
    cursor.execute(sql, list(row.values()))
    
  6. Use INSERT ... SET syntax as an alternative. This syntax pairs each column with its value directly and cannot produce a count mismatch:

    INSERT INTO orders
    SET customer_id = 42,
        product_id  = 17,
        quantity    = 3;
    

Additional Information

  • The SQLSTATE code 21S01 maps to the SQL standard cardinality violation class, meaning the number of values does not match the number of targets.
  • A related error is MySQL 1136 (ER_WRONG_VALUE_COUNT_ON_ROW), which carries the same message but adds a row number: Column count doesn't match value count at row N. Error 1136 appears specifically in multi-row INSERT statements and identifies which row tuple is the offender.
  • Error 1058 is raised regardless of SQL mode (STRICT_TRANS_TABLES, STRICT_ALL_TABLES, etc.) because it is a structural error, not a data-validation error.
  • Prepared statements and parameterized queries are not immune — if the parameter count in the SQL template does not match the bind variable count, most drivers will raise a client-side error before the query reaches MySQL, but the root cause is identical.
  • When using INSERT INTO ... SELECT ..., the analogous error is 1222 (ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), raised when the SELECT column count does not match the target column list.

Frequently Asked Questions

What is the difference between error 1058 and error 1136? Both mean "column count doesn't match value count." Error 1058 is the general form. Error 1136 (ER_WRONG_VALUE_COUNT_ON_ROW) is the multi-row variant and includes the row number in the message (e.g., at row 2), making it easier to locate the offending tuple in a bulk insert.

Can I fix this by omitting the column list? Only if you also supply a value for every column in the table (including auto-increment columns, using DEFAULT or NULL). Omitting the column list makes the statement more fragile — a future ALTER TABLE ADD COLUMN will break it again. Explicitly listing the columns you intend to insert is the safer long-term practice.

Why does my ORM raise this error even though I didn't write any SQL? Some ORM features — bulk insert helpers, raw query methods, or code that constructs SQL from separate column/value collections — can produce a mismatched statement if there is a bug in the calling code. Check the actual SQL sent to MySQL (enable the general query log or use SHOW PROCESSLIST) to see the malformed statement.

Does this error ever occur on SELECT or UPDATE statements? No. Error 1058 is specific to INSERT statements where an explicit column list is provided. UPDATE uses col = value pairs (no separate list), and SELECT does not write data. The nearest equivalent for SELECT in a subquery context is error 1222.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.