The PostgreSQL "function does not exist" error (SQLSTATE 42883) occurs when a function call cannot be matched to any defined function with the same name and argument types. This is commonly caused by mismatched data types, missing extensions, incorrect schema qualification, or typos in the function name. PostgreSQL requires exact matches on both function name and parameter types.
PostgreSQL raises the "function does not exist" error when it cannot find a matching function signature in the database catalog. Unlike some databases that perform implicit type conversions, PostgreSQL requires an exact match between the function name and the argument data types you provide. This means `my_func(bigint)` and `my_func(integer)` are two completely different functions, and if only one is defined, calling the other will fail. The error code 42883 (undefined_function) appears during query planning, before execution. PostgreSQL searches the function catalog, considers the current search_path (schema resolution order), and applies overload resolution rules. If no matching signature is found, the query fails immediately. Common triggers include: data type mismatches (passing an integer where a text parameter is expected), schema issues (function defined in a schema not in search_path), missing extensions (uuid-ossp, pg_trgm, hstore, etc.), function name typos, or insufficient privileges to access the function.
Start by double-checking the function name for typos or case sensitivity issues. PostgreSQL identifiers are case-insensitive unless quoted with double quotes, but unquoted names are lowercased.
-- Check available functions matching the name
\df my_func -- In psql
\df my_* -- Pattern match
-- Or use the pg_proc system catalog
SELECT proname, pg_get_functiondef(oid)
FROM pg_proc
WHERE proname LIKE 'my_func%'
ORDER BY proname;If the function name appears in the list, move to the next step. If not, you need to create the function or check if it was dropped.
PostgreSQL overloads functions by signature, so you must match the exact data types. If you defined my_func(text) but call it with my_func(19) (integer), it will fail.
-- List all signatures for a function
SELECT prosignature
FROM pg_proc
WHERE proname = 'my_func';
-- Or more detailed view:
SELECT pg_get_functiondef(oid)
FROM pg_proc
WHERE proname = 'my_func'
ORDER BY oid DESC;Look at the parameter types. If your call passes integer but the function expects bigint, you need to cast:
-- INCORRECT: integer passed to bigint function
SELECT my_func(42);
-- CORRECT: explicit cast to bigint
SELECT my_func(42::bigint);
-- Or cast in the definition when flexible
CREATE FUNCTION my_func(val bigint) ...The most common fix is to cast your arguments to the expected data types. Use the ::type syntax in PostgreSQL.
-- Original call with type mismatch
SELECT addnewuser(19, 'bbbb', 'aaaaa');
-- ERROR: function addnewuser(integer, unknown, unknown) does not exist
-- Fixed with explicit casts
SELECT addnewuser(19::integer, 'bbbb'::varchar, 'aaaaa'::varchar);
-- Or infer types from context
SELECT addnewuser(19, 'bbbb'::text, 'aaaaa'::text);Common casts:
- ::int or ::integer - 32-bit integer
- ::bigint - 64-bit integer
- ::text or ::varchar - text type
- ::numeric or ::decimal - decimal numbers
- ::date - date type
- ::jsonb - JSON binary format
PostgreSQL resolves function names based on search_path, a list of schemas searched in order. If a function is in a schema not in your search_path, you must qualify it with the schema name.
-- Check current search_path
SHOW search_path;
-- Example output: public, pg_catalog
-- If function is in "analytics" schema, call it explicitly
SELECT analytics.my_func(42);
-- Or add schema to search_path temporarily
SET search_path TO public, analytics, pg_catalog;
SELECT my_func(42); -- Now resolves from analytics schema
-- Or set it for the session
ALTER ROLE current_user SET search_path TO public, analytics, pg_catalog;To find which schema owns the function:
SELECT schemaname, proname
FROM pg_proc
JOIN pg_namespace ON pg_proc.pronamespace = pg_namespace.oid
WHERE proname = 'my_func';Many PostgreSQL functions are provided by extensions that must be explicitly created. After a database restore or migration, extensions may not be installed.
-- List installed extensions
\dx -- In psql
-- Or query pg_extension
SELECT extname FROM pg_extension;
-- Common extensions and their functions:
-- uuid-ossp: uuid_generate_v4(), gen_random_uuid()
-- pg_trgm: similarity(), word_similarity()
-- hstore: each(), akeys(), vals()
-- intarray: icount(), sum()
-- json/jsonb: jsonb_pretty(), jsonb_array_elements()
-- Install a missing extension
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
CREATE EXTENSION IF NOT EXISTS "hstore";
-- If CREATE EXTENSION fails, the extension may not be installed on the server
-- Contact your database administrator or ensure PostgreSQL contrib packages are installedIn rare cases, a function may exist but your role may lack EXECUTE permission. This is similar to "function does not exist" from the user's perspective.
-- Check if you have execute permission
SELECT pg_has_role(current_user, 'postgres', 'MEMBER');
-- Grant execute permission (as superuser or function owner)
GRANT EXECUTE ON FUNCTION my_func(integer) TO public;
GRANT EXECUTE ON FUNCTION my_func(integer) TO user_role;
-- Check function ownership and permissions
SELECT proname, usename, proacl
FROM pg_proc
JOIN pg_user ON pg_proc.proowner = pg_user.usesysid
WHERE proname = 'my_func';If the function truly doesn't exist, you need to create it. If coming from a migration or backup, the function creation script may have failed silently.
-- Example function definition
CREATE OR REPLACE FUNCTION my_func(val integer) RETURNS text AS $$
BEGIN
RETURN 'Result: ' || val;
END;
$$ LANGUAGE plpgsql;
-- Test the function
SELECT my_func(42);
-- Or restore from a SQL dump
psql -d your_database < backup.sql
-- Check for errors during restore
psql -d your_database < backup.sql 2>&1 | grep -i errorIf the function definition script is missing, you may need to reconstruct it from source code or documentation.
PostgreSQL's function resolution uses overload resolution rules similar to C++ or Java. When you call my_func(42, 'text'), PostgreSQL searches for an exact match on signature, then attempts to find one function that matches after implicit casts. If multiple functions match after casts, it reports ambiguity. Use SELECT pg_get_functiondef(regprocedure) to inspect function definitions.
When using prepared statements or parameterized queries (highly recommended for security), the driver must infer parameter types. This can cause issues if the function expects a specific type that the driver cannot infer. Always cast parameters explicitly when using parameterized queries:
// Node.js/pg client
const result = await client.query(
"SELECT my_func($1::bigint)",
[userId] // Cast $1 to bigint
);For database migrations and version upgrades, ensure that: (1) all extensions are installed on the new database, (2) function definitions are recreated in the correct order (functions that call other functions must be defined after their dependencies), (3) search_path is set appropriately for the application, (4) functions in different schemas are qualified in application code or search_path is updated.
When debugging "function does not exist" errors in applications, enable query logging to see the exact SQL being sent:
ALTER SYSTEM SET log_statement = 'all';
SELECT pg_reload_conf();Then check PostgreSQL logs to see the precise function call and argument types. This is far more reliable than guessing from application code.
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL