Skip to content
MySQL Error 1305: FUNCTION Does Not Exist (Fix)

Click to use (opens in a new tab)

MySQL Error 1305: FUNCTION Does Not Exist (Fix)

October 25, 2026 by Chat2DBChat2DB Team

A query that calls a function fails with:

ERROR 1305 (42000): FUNCTION b9.DATE_TRUNC does not exist

The message always names a schema (b9 here), even when you did not write one. That is the most useful clue. MySQL did not find a built-in function with that name, so it looked for a stored function in the current database and did not find one there either.

Error 1305 (ER_SP_DOES_NOT_EXIST) covers several situations: functions from other databases such as PostgreSQL or SQL Server, stored functions that live in a different schema, a stray space between a function name and its parenthesis, procedures called like functions, and even savepoints. This guide walks through each one with output from MySQL 8.4.

How MySQL Resolves a Function Name

When MySQL parses name(...), it checks in this order:

  1. Built-in functions such as CONCAT, NOW, DATE_FORMAT or JSON_EXTRACT.
  2. Loadable functions (UDFs) installed with CREATE FUNCTION ... SONAME.
  3. Stored functions created with CREATE FUNCTION, looked up in the schema you name (util.order_total) or, without a qualifier, in the current default database.

If none match, you get 1305 with the schema it searched. If there is no default database at all, an unqualified call fails earlier with ERROR 1046 (3D000): No database selected.

Cause 1: Functions From Another Database Engine

The most common source of 1305 is SQL written for PostgreSQL, SQL Server or Oracle. These functions do not exist in MySQL:

SELECT DATE_TRUNC('month', created_at) FROM orders;
-- ERROR 1305 (42000): FUNCTION b9.DATE_TRUNC does not exist
 
SELECT STRING_AGG(id, ',') FROM orders;
-- ERROR 1305 (42000): FUNCTION b9.STRING_AGG does not exist
 
SELECT NVL(total, 0) FROM orders;
-- ERROR 1305 (42000): FUNCTION b9.NVL does not exist
 
SELECT GETDATE();
-- ERROR 1305 (42000): FUNCTION b9.GETDATE does not exist
 
SELECT TO_CHAR(created_at, 'YYYY-MM') FROM orders;
-- ERROR 1305 (42000): FUNCTION b9.TO_CHAR does not exist
 
SELECT SPLIT_PART('a,b', ',', 1);
-- ERROR 1305 (42000): FUNCTION b9.SPLIT_PART does not exist

Use the MySQL equivalents:

FromFunctionMySQL equivalent
PostgreSQLDATE_TRUNC('month', d)DATE_FORMAT(d, '%Y-%m-01') or CAST(DATE_FORMAT(d, '%Y-%m-01') AS DATE)
PostgreSQLSTRING_AGG(x, ',')GROUP_CONCAT(x SEPARATOR ',')
PostgreSQLSPLIT_PART(s, ',', 2)SUBSTRING_INDEX(SUBSTRING_INDEX(s, ',', 2), ',', -1)
PostgreSQL / OracleTO_CHAR(d, 'YYYY-MM')DATE_FORMAT(d, '%Y-%m')
OracleNVL(a, b)IFNULL(a, b) or COALESCE(a, b)
OracleLISTAGG(x, ',')GROUP_CONCAT(x SEPARATOR ',')
SQL ServerGETDATE()NOW()
SQL ServerISNULL(a, b)IFNULL(a, b) (MySQL's ISNULL() takes one argument and returns 0 or 1)
SQL ServerLEN(s)CHAR_LENGTH(s)
SQL ServerDATEADD(day, 1, d)DATE_ADD(d, INTERVAL 1 DAY)

GROUP_CONCAT truncates its result at group_concat_max_len bytes (1024 by default). Raise it with SET SESSION group_concat_max_len = 1000000 if you aggregate long lists.

The table covers the frequent ones. For whole queries, the SQL converters on chat2db.ai (opens in a new tab) translate common PostgreSQL syntax to MySQL.

Cause 2: The Stored Function Is in Another Schema

Stored functions belong to a database. A function created in util is not visible from b9 without a qualifier:

CREATE FUNCTION util.order_total(p_id INT) RETURNS DECIMAL(10,2)
  READS SQL DATA
  RETURN (SELECT total FROM b9.orders WHERE id = p_id);
 
USE b9;
SELECT order_total(1);
-- ERROR 1305 (42000): FUNCTION b9.order_total does not exist
 
SELECT util.order_total(1);
-- 10.00

Find where a function actually lives:

SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
FROM information_schema.ROUTINES
WHERE ROUTINE_NAME = 'order_total';
ROUTINE_SCHEMA  ROUTINE_NAME  ROUTINE_TYPE
util            order_total   FUNCTION

If the query returns nothing, the function was never created on this server. That is common after restoring a dump made without --routines. mysqldump includes stored functions and procedures only with --routines (-R). Triggers are included by default, routines are not. Re-dump with --routines, or export the definitions with SHOW CREATE FUNCTION on the source server.

Other ways a function goes missing:

  • The migration that creates it ran in a different database, for example because the connection's default schema differed.
  • An application connects to a new database (a test or tenant database) that was created from table DDL only.
  • A DROP DATABASE removed it. Routines are dropped with their database.

Function names are case-insensitive, so util.ORDER_TOTAL(1) works too. Case is never the cause of 1305 for stored functions.

Cause 3: A Space Before the Parenthesis

With the default SQL mode, MySQL's parser treats the names of certain built-in functions specially, and a space between the name and ( changes how they parse:

SELECT SUM (total) FROM orders;
-- ERROR 1630 (42000): FUNCTION b9.SUM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual
 
SELECT COUNT (*) FROM orders;
-- ERROR 1064 (42000): You have an error in your SQL syntax; ... near '*) FROM orders'

With the space, SUM is not recognised as the aggregate. MySQL then looks for a stored function called SUM and reports error 1630, a close relative of 1305. Most other functions, such as CONCAT ('a', 'b'), accept the space. The affected names are mostly aggregates and functions with special syntax, among them COUNT, SUM, MIN, MAX, GROUP_CONCAT, CAST, EXTRACT, POSITION, SUBSTRING, TRIM, NOW and CURDATE.

Remove the space. Code formatters and hand-written SQL in string templates are the usual cause. The IGNORE_SPACE SQL mode makes the parser accept spaces after all function names, but it also turns every built-in function name into a reserved word, so it can break other queries. Fix the formatting instead.

SET SESSION sql_mode = CONCAT(@@sql_mode, ',IGNORE_SPACE');
SELECT COUNT (*) FROM orders;   -- 2, but not recommended

Cause 4: Calling a Procedure as a Function (or the Reverse)

Functions and procedures are different kinds of stored routines and are called differently. Functions appear in expressions. Procedures are run with CALL:

CREATE PROCEDURE util.refresh_stats() SELECT 'refreshed';
 
SELECT util.refresh_stats();
-- ERROR 1305 (42000): FUNCTION util.refresh_stats does not exist
 
CALL util.refresh_stats();
-- refreshed

The reverse fails the same way: CALL refresh_stats() in the wrong schema gives ERROR 1305 (42000): PROCEDURE b9.refresh_stats does not exist. Check ROUTINE_TYPE in information_schema.ROUTINES to see which one you have.

Cause 5: DROP FUNCTION and DROP PROCEDURE

Dropping a routine that does not exist raises 1305. In migrations and deployment scripts, use IF EXISTS, which downgrades it to a note:

DROP FUNCTION order_total;
-- ERROR 1305 (42000): FUNCTION b9.order_total does not exist
 
DROP FUNCTION IF EXISTS order_total;
SHOW WARNINGS;
-- Note | 1305 | FUNCTION b9.order_total does not exist

Cause 6: Savepoints

Error 1305 is also used for savepoints. A typo, or a savepoint that was already released or rolled back past, produces it:

START TRANSACTION;
SAVEPOINT before_update;
ROLLBACK TO SAVEPOINT before_updte;
-- ERROR 1305 (42000): SAVEPOINT before_updte does not exist
 
RELEASE SAVEPOINT before_update;
ROLLBACK TO SAVEPOINT before_update;
-- ERROR 1305 (42000): SAVEPOINT before_update does not exist

A COMMIT, ROLLBACK, or any statement that causes an implicit commit (most DDL, such as ALTER TABLE or CREATE INDEX) also removes all savepoints. Frameworks that emulate nested transactions with savepoints hit this error when DDL runs inside the transaction.

Not the Same Error: Missing EXECUTE Privilege

If the function exists but the user may not run it, the error is different:

ERROR 1370 (42000): execute command denied to user 'app'@'%' for routine 'util.order_total'

Grant the privilege: GRANT EXECUTE ON FUNCTION util.order_total TO 'app'@'%'; or GRANT EXECUTE ON util.* TO 'app'@'%';.

Quick Checklist

  1. Is it a function from another database engine? Replace it with the MySQL equivalent.
  2. Does it exist? SELECT ROUTINE_SCHEMA, ROUTINE_TYPE FROM information_schema.ROUTINES WHERE ROUTINE_NAME = '...'.
  3. Is it in another schema? Qualify the call: schema.function(...).
  4. Was the dump made without --routines? Restore the routines.
  5. Is there a space before (? Remove it.
  6. Is it a procedure? Use CALL.

When a database has many stored routines spread across schemas, browsing them is easier in a GUI. Chat2DB (opens in a new tab) lists functions and procedures per schema with their source, and its AI assistant can translate PostgreSQL or SQL Server functions in your queries into their MySQL equivalents.

FAQ

Why does the error show my database name before the function?

Because MySQL looked for a stored function in your current default database after it found no built-in function with that name. The schema in the message is where it searched, not necessarily where the function lives.

Does mysqldump include stored functions?

Only with --routines (or -R). Without it, a restored database has all tables and triggers but no stored functions or procedures, and calls fail with error 1305. Events need --events.

Can I create a function with the same name as a built-in one?

You can create a stored function named like a built-in, but unqualified calls still resolve to the built-in function. Call yours with the schema prefix (util.my_func()), or better, choose a name that does not clash.