How to fix ER_WINDOW_FRAME_START_ILLEGAL (3584): Illegal frame start in MySQL
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]
)- Review the window frame specification syntax
- Replace GROUPS with ROWS or RANGE
- Verify frame boundary keywords are valid
- Use correct frame boundary values
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
- 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)
- Using FROM LAST instead of FROM FIRST in frame specification
- Attempting to use EXCLUDE clause which is parsed but produces error
- Using IGNORE NULLS instead of RESPECT NULLS in frame specification
How to fix "ER_WINDOW_FRAME_START_ILLEGAL (3584): Illegal frame start"
Check your OVER() clause for the frame specification. The valid syntax is:
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
MySQL does not support GROUPS frame units. If your query uses GROUPS, replace it with ROWS or RANGE:
-- 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;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)
-- 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
);When using N PRECEDING or N FOLLOWING, N must be a non-negative numeric literal or parameter marker:
-- 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;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:
-- 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
- ๐MySQL Official Documentation
- ๐MySQL 8.0 Window Function Frame Specification(Official Docs)
- ๐MySQL 8.0 Window Function Restrictions(Official Docs)
- ๐MySQL 8.0 Window Function Concepts and Syntax(Official Docs)
- ๐MySQL 8.4 Window Function Frame Specification(Official Docs)