PostgreSQL Error 2201E: invalid argument for logarithm
PostgreSQL error code 2201E (invalid_argument_for_logarithm) is thrown when you pass a zero or negative number to a logarithmic function such as log() or ln(). Mathematically, logarithms are only defined for positive real numbers, so the database engine raises this error to enforce that mathematical constraint. If you're hitting this error in production, it almost always means your data contains unexpected zero or negative values that weren't caught before the calculation.
Top 3 Causes
1. Passing Zero or Negative Values Directly
The most common cause is simply having 0 or negative numbers in the column you're feeding into log() or ln().
-- This will throw 2201E if any sales_amount <= 0
SELECT log(sales_amount) FROM sales;
-- Reproduce the error intentionally
SELECT log(0); -- ERROR: invalid argument for logarithm
SELECT log(-5); -- ERROR: invalid argument for logarithm
SELECT ln(-1); -- ERROR: invalid argument for logarithm
2. NULL Replaced with Zero via COALESCE
Developers often use COALESCE to handle NULLs but accidentally replace them with 0, which then gets passed to log().
-- This looks safe but will cause 2201E when amount IS NULL
SELECT log(COALESCE(amount, 0)) FROM transactions;
-- NULL itself is fine — log(NULL) returns NULL without error
SELECT log(NULL); -- Returns: NULL (no error)
3. Unvalidated Data from ETL or External Sources
When data flows in from external systems or ETL pipelines without range validation, rogue zero or negative values can silently enter your tables and blow up downstream log calculations.
-- Check for problematic values before processing
SELECT
COUNT(*) FILTER (WHERE value <= 0) AS invalid_count,
COUNT(*) FILTER (WHERE value IS NULL) AS null_count,
COUNT(*) FILTER (WHERE value > 0) AS valid_count
FROM source_data;
Quick Fix Solutions
Use CASE WHEN or NULLIF to guard your log calls:
-- Safe pattern using CASE WHEN
SELECT
id,
CASE
WHEN sales_amount > 0 THEN log(sales_amount)
ELSE NULL
END AS log_sales
FROM sales;
-- Safe pattern using WHERE filter
SELECT id, log(value)
FROM measurements
WHERE value > 0;
-- Fix the COALESCE-zero anti-pattern
-- Instead of log(COALESCE(amount, 0)), use:
SELECT log(NULLIF(COALESCE(amount, 1), 0)) FROM transactions;
-- Create a reusable safe_log function
CREATE OR REPLACE FUNCTION safe_log(p_value NUMERIC)
RETURNS NUMERIC AS $$
SELECT CASE WHEN p_value > 0 THEN log(p_value) ELSE NULL END;
$$ LANGUAGE sql IMMUTABLE;
-- Now use it anywhere without worrying about 2201E
SELECT safe_log(sales_amount) FROM sales;
Prevention Tips
1. Add a CHECK constraint at the table level
Stop bad data at the source by enforcing positivity directly on the column.
-- At table creation
CREATE TABLE sensor_readings (
id SERIAL PRIMARY KEY,
reading NUMERIC NOT NULL,
CONSTRAINT chk_positive_reading CHECK (reading > 0)
);
-- On an existing table
ALTER TABLE sales
ADD CONSTRAINT chk_positive_amount CHECK (sales_amount > 0);
2. Validate data before log-heavy ETL steps
Build a pre-flight check into your pipeline that aborts or quarantines bad rows before any logarithmic transformation runs.
-- Quarantine invalid rows
INSERT INTO invalid_data_log (source_table, row_id, bad_value, detected_at)
SELECT 'source_data', id, value, NOW()
FROM source_data
WHERE value <= 0 OR value IS NULL;
-- Only process clean rows
INSERT INTO processed_results (id, log_value)
SELECT id, log(value)
FROM source_data
WHERE value > 0;
Related Errors
| Code | Name | Description |
|---|---|---|
2201F |
invalid_argument_for_power_function |
Raised by power() with invalid base/exponent |
22012 |
division_by_zero |
Similar domain-violation class for division |
22003 |
numeric_value_out_of_range |
Result exceeds the numeric type's range |
The key takeaway: never trust input data. Always guard logarithmic functions with a positivity check, and push that validation as far upstream as possible — ideally into a CHECK constraint on the table itself.
📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.
Top comments (0)