Common SQL Errors

PostgreSQL 2F004 reading_sql_data_not_permitted error explained and fixed

August 4, 2025

PostgreSQL raises 2F004 reading_sql_data_not_permitted when a function or procedure marked NO SQL or with lower access tries to run a query that reads table data.

Sign up for the latest in common SQL errors from the Galaxy Team!
Welcome to the Galaxy, Guardian!
You'll be receiving a confirmation email

Follow us on twitter :)
Oops! Something went wrong while submitting the form.

What is the reading_sql_data_not_permitted error?

reading_sql_data_not_permitted (SQLSTATE 2F004) means the routine was declared without permission to read tables, yet it attempted a SELECT or similar. Alter the function with SQL DATA ACCESS READS SQL DATA (or MODIFIES SQL DATA) or remove the NO SQL clause to resolve the error.

Error Highlights

Typical Error Message

reading_sql_data_not_permitted

Error Type

Permission Error

Language

PostgreSQL

Symbol

reading_sql_data_not_permitted

Error Code

2F004

SQL State

Explanation

Table of Contents

What is the reading_sql_data_not_permitted error?

PostgreSQL returns SQLSTATE 2F004 when a function, procedure, or trigger routine attempts to access table data but its definition forbids that level of access.

The SQL Standard defines data-access modifiers such as NO SQL, CONTAINS SQL, READS SQL DATA, and MODIFIES SQL DATA. PostgreSQL enforces those flags from version 14 onward for SQL-language routines.

A mismatch triggers reading_sql_data_not_permitted.

What Causes This Error?

The routine is declared NO SQL or CONTAINS SQL yet executes a SELECT, cursor, or other read operation. PostgreSQL blocks the call and raises 2F004.

Using READS SQL DATA but then calling INSERT, UPDATE, or DELETE also fails because writes are considered more powerful than reads.

How to Fix reading_sql_data_not_permitted

Grant the routine the correct data-access level.

Use ALTER FUNCTION / PROCEDURE to switch to READS SQL DATA for reading queries or MODIFIES SQL DATA when writes are required.

Alternatively, rewrite the routine so it no longer issues SQL that violates its declared restrictions.

Common Scenarios and Solutions

Language SQL functions migrated from older PostgreSQL versions often default to NO SQL. Updating their definitions usually restores functionality.

Trigger functions created by ORMs sometimes inherit restrictive flags.

Adjusting the generated DDL or adding a post-migration script resolves the problem.

Best Practices to Avoid This Error

Always align the data-access flag with the most powerful operation inside the routine at creation time.

Include routine linting in CI pipelines.

Galaxy’s AI copilot can scan CREATE FUNCTION statements and suggest the correct access modifier before deployment.

Related Errors and Solutions

2F003 - modifies_sql_data_not_permitted: raised when a routine marked READS SQL DATA performs a write.

38001 - invalid_sql_statement_name: often appears when dynamic SQL resolves to a forbidden statement inside a restricted routine.

.

Common Causes

Function declared NO SQL but running SELECT

Older code or generated DDL frequently adds NO SQL automatically. Any SELECT inside those bodies conflicts with the declaration and triggers 2F004.

Routine declared READS SQL DATA but issues INSERT/UPDATE/DELETE

Write operations exceed the permission implied by READS SQL DATA, causing PostgreSQL to reject the call.

ORM or migration tool sets default flag incorrectly

Some tools set CONTAINS SQL for every function.

If the body later evolves to include table queries, the mismatch surfaces at runtime.

Version upgrade tightened enforcement

Databases upgraded to PostgreSQL 14+ see this error on first call because earlier versions ignored the flag.

.

Related Errors

FAQs

Does changing the data-access flag require dropping the function?

No. Use ALTER FUNCTION or ALTER PROCEDURE to modify the flag in place without losing dependent objects.

Will raising the flag to MODIFIES SQL DATA hurt performance?

Performance is unaffected. The flag controls permissible operations, not execution speed.

Why did the error appear after upgrading PostgreSQL?

Versions 14 and later enforce the SQL Standard flags. Older versions silently ignored mismatches.

Can Galaxy prevent this error automatically?

Yes. Galaxy’s AI copilot inspects CREATE FUNCTION statements and suggests the correct flag before you run them, reducing runtime failures.

Start Querying with the Modern SQL Editor Today!
Welcome to the Galaxy, Guardian!
You'll be receiving a confirmation email

Follow us on twitter :)
Oops! Something went wrong while submitting the form.

Check out some other errors

Trusted by top engineers on high-velocity teams
Aryeo Logo
Assort Health
Curri
Rubie Logo
Bauhealth Logo
Truvideo Logo