How to fix ER_WINDOW_FRAME_START_ILLEGAL (3584): Illegal frame start in MySQL

MySQLINTERMEDIATEHIGHUpdated Dec 28, 2025ยท 109 views

This error occurs when defining a window function with an invalid starting boundary in the OVER() clause. The frame start specification violates MySQL's window function syntax requirements.

Quick fix

Fixes 3584

OVER (
  [PARTITION BY ...]
  [ORDER BY ...]
  [ROWS|RANGE BETWEEN frame_start AND frame_end]
)
  1. Review the window frame specification syntax
  2. Replace GROUPS with ROWS or RANGE
  3. Verify frame boundary keywords are valid
  4. Use correct frame boundary values
mysql โ€” error
OVER (
[PARTITION BY ...]
[ORDER BY ...]
[ROWS|RANGE BETWEEN frame_start AND frame_end]
)
ER_WINDOW_FRAME_START_ILLEGAL (3584): Illegal frame start

What this error means

The ER_WINDOW_FRAME_START_ILLEGAL error occurs when MySQL encounters an invalid frame boundary specification in a window function. Window functions in MySQL use a frame specification to define which rows are included in the calculation. The frame start (the beginning boundary of the frame) must follow valid MySQL syntax. Common causes include using unsupported frame specifications, incorrect syntax for boundary keywords, or attempting to use features that MySQL does not yet support like GROUPS frame units.

Typical symptoms

  • Query fails with error code 3584 when using OVER() clause
  • Window function calculations do not execute
  • Error message appears when running SELECT statements with ROW_NUMBER(), RANK(), or aggregate window functions
  • Application receives MySQL error during query execution

Common causes

  1. Using GROUPS frame units (parsed but not supported in MySQL)
  2. Invalid frame boundary syntax like negative values or unsupported keywords
  3. Incorrect frame specification format (missing BETWEEN, wrong keywords)
  4. Using FROM LAST instead of FROM FIRST in frame specification
  5. Attempting to use EXCLUDE clause which is parsed but produces error
  6. Using IGNORE NULLS instead of RESPECT NULLS in frame specification

How to fix "ER_WINDOW_FRAME_START_ILLEGAL (3584): Illegal frame start"

1Review the window frame specification syntax

Check your OVER() clause for the frame specification. The valid syntax is:

sql
OVER (
  [PARTITION BY ...]
  [ORDER BY ...]
  [ROWS|RANGE BETWEEN frame_start AND frame_end]
)

The frame_start can be:
- UNBOUNDED PRECEDING
- N PRECEDING (where N is a number)
- CURRENT ROW

2Replace GROUPS with ROWS or RANGE

MySQL does not support GROUPS frame units. If your query uses GROUPS, replace it with ROWS or RANGE:

sql
-- INCORRECT (causes error):
SELECT name, salary,
  ROW_NUMBER() OVER (ORDER BY salary GROUPS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
FROM employees;

-- CORRECT:
SELECT name, salary,
  ROW_NUMBER() OVER (ORDER BY salary ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
FROM employees;
3Verify frame boundary keywords are valid

Ensure your frame boundaries use only supported keywords:

Supported:
- UNBOUNDED PRECEDING
- UNBOUNDED FOLLOWING
- CURRENT ROW
- N PRECEDING
- N FOLLOWING

Unsupported (will cause error):
- FROM LAST (use FROM FIRST)
- IGNORE NULLS (use RESPECT NULLS)
- EXCLUDE (any variant)

sql
-- INCORRECT:
SELECT * FROM users
WINDOW user_window AS (
  ORDER BY created_at
  ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW
);

-- CORRECT:
SELECT * FROM users
WINDOW user_window AS (
  ORDER BY created_at
  ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
);
4Use correct frame boundary values

When using N PRECEDING or N FOLLOWING, N must be a non-negative numeric literal or parameter marker:

sql
-- CORRECT:
SELECT name, salary,
  AVG(salary) OVER (
    ORDER BY hire_date
    ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING
  ) as avg_surrounding
FROM employees;

-- CORRECT with INTERVAL (for temporal data):
SELECT order_date, amount,
  SUM(amount) OVER (
    ORDER BY order_date
    RANGE BETWEEN INTERVAL 7 DAY PRECEDING AND CURRENT ROW
  ) as weekly_total
FROM orders;
5Simplify frame specification if possible

If your window function ignores frame clauses (ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, NTILE, PERCENT_RANK, CUME_DIST), you can omit the frame clause entirely:

sql
-- Frame clause is ignored and causes complexity:
SELECT name,
  ROW_NUMBER() OVER (ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM employees;

-- Simpler (frame is ignored anyway):
SELECT name,
  ROW_NUMBER() OVER (ORDER BY salary)
FROM employees;

Advanced notes

MySQL window function support was introduced in version 8.0. Some frame specifications from SQL standard are parsed but not yet supported. If you're using an older MySQL version (pre-8.0), window functions are not available at all. The error specifically refers to the frame start boundary; a similar error ER_WINDOW_FRAME_END_ILLEGAL (3585) exists for frame end boundaries. When using RANGE frame units with numeric or temporal expressions, the ORDER BY clause must also use a compatible numeric or temporal expression. Dynamic frame endpoints that depend on the current row value are also unsupported in MySQL.

Frequently asked questions

What does "3584" mean?
The ER_WINDOW_FRAME_START_ILLEGAL error occurs when MySQL encounters an invalid frame boundary specification in a window function. Window functions in MySQL use a frame specification to define which rows are included in the calculation. The frame start (the beginning boundary of the frame) must follow valid MySQL syntax.
How do I fix "3584"?
This error occurs when defining a window function with an invalid starting boundary in the OVER() clause. The frame start specification violates MySQL's window function syntax requirements.
What causes "3584"?
Using GROUPS frame units (parsed but not supported in MySQL) Invalid frame boundary syntax like negative values or unsupported keywords Incorrect frame specification format (missing BETWEEN, wrong keywords)
Is the "3584" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading