Nullable is a claim about the world
It says this fact may legitimately not exist.
Making a column nullable is frequently done to avoid an obstacle: the import has rows without it, the form does not collect it yet, backfilling would take an afternoon. Each is a reasonable short-term motive and the result is a permanent statement that the value may be absent.
The cost is paid by every consumer afterwards. Every query has to decide what an absent value means, and different consumers decide differently. One report treats it as zero, another excludes the row, a third treats it as unknown, and the three produce different totals that somebody then has to reconcile.
The discipline is to ask what an absent value would mean. If it means the fact genuinely does not apply, nullable is correct and the meaning should be documented. If it means the value exists and was not captured, that is a data quality problem being encoded as a schema decision, and it will not be revisited.
The same reasoning applies to sentinel values, which are worse. A date of the first of January nineteen hundred, an amount of negative one, or a name of unknown are all absences wearing a disguise, and every consumer has to know the convention to avoid including them in a calculation.
There is a related decision worth making explicitly, which is whether absence is represented once or several times. A system that uses null in some places, an empty string in others and a zero elsewhere for the same conceptual absence forces every consumer to handle three cases, and the third one is always the one somebody forgets.