Troubleshooting Guide: Error 1940 — “Cannot create %S_MSG on view ‘%.*ls’. It does not have a unique clustered index.”
Why This Error Happens
This error occurs when you attempt to create an indexed (materialized) view or add a unique/primary constraint on a view in SQL Server 2025 without first establishing a unique clustered index on that view. SQL Server requires the first index created on a view to be a unique clustered index because this physically materializes the view’s result set on disk, and subsequent nonclustered indexes depend on that structure existing first. This commonly happens when the CREATE INDEX statement omits the UNIQUE keyword, when the view’s SELECT statement lacks deterministic columns, or when the underlying columns referenced can’t guarantee row uniqueness.
Step-by-Step Resolution Guide
Step 1: Verify the View Definition Meets Indexing Requirements
- Confirm the view is created
WITH SCHEMABINDING, as this is mandatory for any indexed view. - Ensure the
SELECTstatement does not useSELECT *, outer joins,UNION, subqueries, or non-deterministic functions (e.g.,GETDATE()). - Run the following to inspect the view’s current definition:
EXEC sp_helptext 'YourSchema.YourViewName';
Step 2: Create the Correct Unique Clustered Index First
- Identify a column or combination of columns in the view that guarantees row-level uniqueness (e.g., a primary key column from the base table).
- Execute the clustered index creation before attempting any other index:
CREATE UNIQUE CLUSTERED INDEX IX_ViewName_Unique
ON YourSchema.YourViewName (UniqueColumn1, UniqueColumn2);
- Do not attempt
CREATE INDEX(nonclustered) on the view until this step succeeds.
Step 3: Adjust Session-Level SET Options
- Confirm the following SET options are correctly configured in your session or connection string, as indexed views require strict settings:
ANSI_NULLS ONANSI_PADDING ONANSI_WARNINGS ONARITHABORT ONCONCAT_NULL_YIELDS_NULL ONQUOTED_IDENTIFIER ONNUMERIC_ROUNDABORT OFF- Set these explicitly at the top of your script before creating the index:
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
SET ARITHABORT ON;
Step 4: Rebuild Dependent Objects
- If the view was altered to fix schemabinding or column issues, check for and rebuild any dependent indexes, statistics, or foreign views that failed due to the broken dependency chain.
- Use
sys.sql_expression_dependenciesto map out objects relying on this view before re-running index creation scripts.
Alternative or Verification Steps
- Verify the fix by querying
sys.indexesand confirmingindex_id = 1(clustered) exists withis_unique = 1for the view’s object ID:
SELECT i.name, i.index_id, i.is_unique
FROM sys.indexes i
WHERE i.object_id = OBJECT_ID('YourSchema.YourViewName');
- If the unique clustered index still fails to create, check for duplicate data in the underlying base tables using a
GROUP BY ... HAVING COUNT(*) > 1query on your intended key columns — duplicates will block uniqueness enforcement even if the syntax is correct.