ERROR 1407 occurs when you provide an invalid SQLSTATE value in a SIGNAL statement within a stored procedure or condition handler. SQLSTATE values must be exactly 5 characters and cannot start with "00" (which indicates success). Use "45000" for user-defined exceptions.
ERROR 1407 (SQLSTATE 42000) is a MySQL syntax error that occurs when you attempt to signal an error using an invalid SQLSTATE value in a stored procedure, trigger, or condition handler. SQLSTATE is a five-character code defined by the SQL standard that indicates the outcome of SQL statements. The first two characters represent the error class (where "00" indicates success), and the last three represent the subclass. When MySQL encounters an improperly formatted or semantically invalid SQLSTATE value in a SIGNAL or DECLARE CONDITION statement, it raises this error to prevent the creation of invalid error handlers. This error is specific to stored procedures and triggers because these features support custom error handling through the SIGNAL and RESIGNAL statements. The error typically manifests when attempting to define a condition or signal an exception with a malformed SQLSTATE value.
Check that your SQLSTATE value is exactly 5 characters long. Invalid examples:
-- TOO SHORT (3 chars)
DECLARE my_condition CONDITION FOR SQLSTATE "123";
-- TOO LONG (6 chars)
DECLARE my_condition CONDITION FOR SQLSTATE "123456";
-- CORRECT (5 chars)
DECLARE my_condition CONDITION FOR SQLSTATE "45000";Each SQLSTATE value must have exactly 5 characters.
SQLSTATE values beginning with "00" are reserved by SQL standard to indicate success, and cannot be used in error signaling. These will cause ERROR 1407:
-- WRONG: "00" indicates success
DECLARE my_condition CONDITION FOR SQLSTATE "00123";
-- CORRECT: Use "45000" for user-defined exceptions
DECLARE my_condition CONDITION FOR SQLSTATE "45000";Valid SQLSTATE prefixes for error conditions:
- "01" = warnings
- "02" = not found
- "45" = user-defined exceptions
- "HY" = general error class
The recommended SQLSTATE value for user-defined exceptions in stored procedures is "45000". This is the generic unhandled user-defined exception code:
DELIMITER //
CREATE PROCEDURE validate_age(IN p_age INT)
BEGIN
DECLARE invalid_age CONDITION FOR SQLSTATE "45000";
IF p_age < 0 THEN
SIGNAL invalid_age SET MESSAGE_TEXT = "Age cannot be negative";
END IF;
END //
DELIMITER ;This procedure now properly defines a condition with valid SQLSTATE "45000" and signals it when validation fails.
If you're using SIGNAL directly without declaring a condition, ensure the SQLSTATE is valid:
-- WRONG: Will cause ERROR 1407
SIGNAL SQLSTATE "00000" SET MESSAGE_TEXT = "Error";
-- CORRECT: Use valid SQLSTATE
SIGNAL SQLSTATE "45000" SET MESSAGE_TEXT = "An error occurred";In triggers:
CREATE TRIGGER validate_insert BEFORE INSERT ON users
FOR EACH ROW
BEGIN
IF NEW.email IS NULL THEN
SIGNAL SQLSTATE "45000" SET MESSAGE_TEXT = "Email cannot be null";
END IF;
END;If using condition names (rather than inline SQLSTATE), ensure each condition is declared with a valid SQLSTATE:
DELIMITER //
CREATE PROCEDURE process_order(IN p_order_id INT)
BEGIN
-- Declare conditions properly
DECLARE invalid_order CONDITION FOR SQLSTATE "45001";
DECLARE processing_error CONDITION FOR SQLSTATE "45002";
-- Use them in handlers
DECLARE EXIT HANDLER FOR 1451
BEGIN
SIGNAL invalid_order SET MESSAGE_TEXT = "Cannot process order with related records";
END;
-- Procedure logic here
END //
DELIMITER ;Each DECLARE CONDITION must have a proper 5-character SQLSTATE that does not start with "00".
SQLSTATE values follow the SQL standard (ANSI SQL and ODBC) structure. The first two characters represent the class and the last three the subclass. Key classes include: "01" for warnings, "02" for NOT FOUND, "07" for dynamic SQL errors, "42" for syntax errors (like this one). When MySQL cannot map a specific error number to a SQLSTATE, it uses "HY000" (general error). The "45" class is reserved for user-defined exceptions and is the recommended choice for custom SIGNAL statements in stored procedures. Some MySQL versions may have slightly different SQLSTATE handling, so always verify with your specific MySQL version documentation.
EE_WRITE (3): Error writing file
How to fix "EE_WRITE (3): Error writing file" in MySQL
CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters
How to fix "CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters" in MySQL
CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed
How to fix "CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed" in MySQL
ERROR 1146: Table 'database.table' doesn't exist
How to fix "ERROR 1146: Table doesn't exist" in MySQL
ERROR 1040: Too many connections
How to fix "ERROR 1040: Too many connections" in MySQL