Incident brief
Wrong object type (DROP INDEX on a table)
Object-specific DDL like DROP INDEX only accepts that object type; running DROP INDEX against a table raises this wrong-object-type error with a hint to use DROP TABLE.
What lands in your log
ERROR: "widgets" is not an index
In 10 seconds
- What triggers it
- Run DROP INDEX against a name that is actually a table.
- Fix
- Use the DDL that matches the object type, DROP TABLE for a table, DROP INDEX for an index.
- Proof
- Reproduced on PostgreSQL 18.4 → A single statement reproduces SQLSTATE 42809; DROP INDEX on a table is rejected with a hint naming the right command.
Fix
What to do right now
Application-level steps for this error.
- Use the DDL that matches the object type, DROP TABLE for a table, DROP INDEX for an index.
- Check the object type (\d in psql, or pg_class.relkind) before scripting the drop.
-- Use DROP TABLE to remove a table.
DROP TABLE widgets;For this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
Resolve the existing object and relkind and its relkind before deciding to reuse, rename, or drop it.
Existing object and relkind with this name
Replace the literal with the identifier from the error; relkind distinguishes table, index, view, sequence, and partition.
SELECT n.nspname AS schema_name, c.relname, c.relkind
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = '<object_name>'
ORDER BY n.nspname, c.relname
LIMIT 50;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)
42809 → wrong_object_typeRead the full section on postgresql.org →
Dropping a table with DROP INDEX
'widgets' is a table, not an index, so DROP INDEX raises 'widgets is not an index' and hints to use DROP TABLE.The session continues normally
DROP INDEX failed as a standalone statement, so the session carries no leftover transaction state into its next query.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.
- 1Run DROP INDEX against a name that is actually a table.
- 2PostgreSQL looks the name up and finds it is a table, not an index.
- 3The mismatch aborts the statement with SQLSTATE 42809 and a hint to use DROP TABLE.
A cleanup script assumed a name was an index and DROP INDEX failed because the object was really a table.
CREATE TABLE widgets(id int);DROP INDEX widgets;SELECT 'ok' AS session_after_error;What PostgreSQL actually returned
CREATE TABLEERROR: "widgets" is not an index
HINT: Use DROP TABLE to remove a table. session_after_error
---------------------
ok
(1 row)The object drops cleanly once the command matches its type.
Without this
Before: DROP INDEX rejects the table
With this, tested
After: DROP TABLE removes it
- A second operational test: exact SQL, raw output, measured result, and engineer notes
Card required. Cancel before day 7 and you are not charged.
Runbook to fix this
Runbooks for this incident
Full step-by-step fixes for the condition behind this error: the diagnosis, the exact SQL, and output captured in the lab.
- Eliminate redundant and duplicate indexesWrites are slow and the same leading column is indexed three different ways.Pro
- Find and drop unused indexesAn index nobody has scanned in years that every INSERT still pays for.Pro
- Rebuild a bloated index with REINDEX CONCURRENTLYThe index is four times the size of its entries and scans keep getting slower.Pro
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.