Incident brief
Duplicate table alias
Each table or alias in a FROM clause must have a unique name; using the same alias twice raises this duplicate-alias error.
What lands in your log
ERROR: table name "a" specified more than once
In 10 seconds
- What triggers it
- Write a FROM clause that references the same table twice with the same alias.
- Fix
- Give each FROM entry a distinct alias.
- Proof
- Reproduced on PostgreSQL 18.4 → A single query reproduces SQLSTATE 42712; the repeated alias is rejected before the join runs.
Fix
What to do right now
Application-level steps for this error.
- Give each FROM entry a distinct alias.
- When self-joining a table, alias each instance differently (t1, t2).
-- Give each FROM entry a distinct alias.
SELECT * FROM ref_demo a, ref_demo b;For this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
Duplicate table alias is fixed in the statement text. PostgreSQL stores no failed parse tree, so use the error POSITION against the exact SQL sent by the driver and inspect real column/function names.
Candidate columns on the referenced relations
Replace the relation array with the tables/aliases in the failing statement.
SELECT attrelid::regclass AS table_name, attnum, attname,
format_type(atttypid, atttypmod) AS data_type
FROM pg_attribute
WHERE attrelid = ANY (ARRAY[
to_regclass('<first_relation>'),
to_regclass('<second_relation>')
]::regclass[])
AND attnum > 0 AND NOT attisdropped
ORDER BY attname, table_name;Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual, not paraphrased.
PostgreSQL 18 Documentation, Appendix A. PostgreSQL Error Codes (Table A.1, Class 42, Syntax Error or Access Rule Violation)
42712 → duplicate_aliasRead the full section on postgresql.org →
Reusing a table alias
Both FROM entries are named 'a', so PostgreSQL raises 'table name a specified more than once'.The session continues normally
The duplicate-alias check failed at parse time, outside a transaction, so session B's next statement is unaffected.Reproduce & verify
A real, single-session PostgreSQL reproduction
A literal transcript of SQL run against a live PostgreSQL instance in an isolated lab. The commands below are exactly what was executed.
- 1Write a FROM clause that references the same table twice with the same alias.
- 2PostgreSQL builds the range table and finds two entries with the same name.
- 3The statement aborts with SQLSTATE 42712.
A self-join reused the same alias for both copies of a table, and the planner could not tell the two apart.
CREATE TABLE ref_demo(label text);
INSERT INTO ref_demo VALUES ('a');SELECT * FROM ref_demo a, ref_demo a;SELECT 'ok' AS session_after_error;What PostgreSQL actually returned
CREATE TABLE
INSERT 0 1ERROR: table name "a" specified more than once session_after_error
---------------------
ok
(1 row)The join runs once each table reference has a unique alias.
Without this
Before: a repeated alias aborts
With this, tested
After: distinct aliases join cleanly
- A second operational test: exact SQL, raw output, measured result, and engineer notes
Card required. Cancel before day 7 and you are not charged.
Connected
Everything this error touches
Every page this SQLSTATE connects to: the concept that explains it, the runbooks that fix it, the parameters you tune to prevent it, and the sibling errors it travels with. All real cross-references. Jump straight in, or open the full interactive map.
Verification
- Last verified
- 2026-07-24 (isolated lab, PostgreSQL 18.4)
- Verification scope
- Verified against PostgreSQL 18.4 in an isolated lab environment
- Audit status
- reviewed
Went further?
Pro unlocks the second lab proof
Free page stops the bleeding. Pro adds the operational test, SQLSTATE audit, and deeper evidence, same error, more certainty.