A Rouen duck is considering the holes in a sidewalk.

We leave the archive arc behind and enter the first of several backward-compatibility GUCs. array_nulls controls whether the array input parser treats an unquoted NULL as an actual SQL null or as the four-character string "NULL". Default is on; context is user; it has been on by default since PostgreSQL 8.2, which shipped in December 2006.

The mechanic:

1SET array_nulls = on; -- the default
2SELECT '{a,NULL,b}'::text[];
3-- → {a,NULL,b} (three elements; middle one is a true SQL NULL)
4
5SET array_nulls = off;
6SELECT '{a,NULL,b}'::text[];
7-- → {a,"NULL",b} (three elements; middle one is the literal string "NULL")

The parameter exists so that applications written against pre-8.2 PostgreSQL, which genuinely did store the string "NULL" when it saw that token, can continue to function unchanged. In 2026, such applications are now one of: extinct, museum pieces, or load-bearing infrastructure at an institution that does not know what it has.

One subtlety the docs bother to call out: turning array_nulls off does not prevent you from creating arrays with nulls. ARRAY[1, NULL, 2] and explicitly quoted '{1,"NULL",2}' still work as you’d expect — the constructor syntax never went through the string-level array parser, so the GUC doesn’t apply. array_nulls only governs the literal-array text-parsing path.

Recommendation: Leave it alone. If you’re migrating a pre-8.2 application and its behavior depends on NULL-as-string, you have a bigger problem than this GUC; the rest of the codebase assumes a version of PostgreSQL that stopped being supported in 2011. Fix the app, don’t flip the switch.