# 2201E — invalid_argument_for_logarithm

> Source-backed reference for PostgreSQL SQLSTATE 2201E.
---

# 2201E

## At a glance {#at-a-glance}
Logarithm functions reject zero and negative inputs at their defined-domain guards. Fixed float paths report `cannot take logarithm of zero` or `cannot take logarithm of a negative number`; numeric `ln` and base-log paths apply the same SQLSTATE while handling NaN and infinities separately.

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| Field | Value |
| --- | --- |
| SQLSTATE | `2201E` |
| Condition | `invalid_argument_for_logarithm` |
| Status | `active` |
| Known present by | `8.0.0` |
| Locked snapshots | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| Macros | `ERRCODE_INVALID_ARGUMENT_FOR_LOG` |
| Aliases | `—` |

<!-- source facts: data/errcodes/2201E.json -->
<!-- END SQLSTATE FACTS -->

## Meaning {#meaning}
2201E is a logarithm domain error, not a generic numeric overflow. In `float.c`, `ln()` and `log()` reject an argument equal to zero and then one less than zero. Numeric `ln` rejects negative infinity but returns numeric NaN or positive infinity unchanged; numeric base-log rejects a negative or zero base/argument and has defined NaN/infinity results for some positive special-value combinations.

## Diagnosis {#diagnosis}
Read the function signature and the actual numeric type before changing the value. Match the primary message: zero and negative inputs are different guards. For float inputs, NaN does not satisfy either comparison and therefore is not this particular guard; later float overflow or underflow reports are separate conditions. Preserve the input and business rule while checking whether the logarithm domain is really intended.

## Response {#response}
Supply a value in the domain required by the named logarithm function, or change the business rule explicitly. If an ERROR occurred inside an explicit transaction, roll back or roll back to the existing savepoint before retrying; an autocommit client can retry the corrected statement. Casting blindly can move the value without making the operation defined.

## Versions {#versions}
The locked catalogue records this condition from 8.0.0; the fixed source paths here are PostgreSQL 18.6. No natural runtime observation is claimed for this page.

## Related {#related}
[`22003`](../22003/), [`22012`](../22012/)

## Sources {#sources}
Fixed paths include [`src/backend/utils/adt/float.c#L1687-1747`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/float.c#L1687) and [`src/backend/utils/adt/numeric.c#L3935-4020`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/numeric.c#L3935) plus [`#L11156-11168`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/numeric.c#L11156), which bind the zero/negative guards and special-value branches. The structured [evidence record](../data/evidence/2201e.json) retains the exact message roles and scope boundary; no natural runtime was run.
