Troubleshooting Guide: SQL Server Error 8166 — Constraint Names Cannot Begin with a Number Sign (#)
Why This Error Happens
This error occurs because SQL Server reserves the number sign (#) prefix to denote temporary objects, such as temporary tables or temporary constraints in tempdb. When a user or an automated script explicitly names a constraint (e.g., a PRIMARY KEY, FOREIGN KEY, CHECK, or DEFAULT constraint) starting with “#”, the SQL Server parser rejects the identifier because it conflicts with the engine’s internal naming convention for temporary scope. This is typically caused by dynamic SQL generation scripts, ORM migrations, or copy-pasted T-SQL templates that incorrectly concatenate a “#” symbol into the constraint name variable.
Step-by-Step Resolution Guide
Step 1: Identify the Offending T-SQL Script
- Locate the specific
CREATE TABLEorALTER TABLEstatement that triggered the error in SQL Server Management Studio (SSMS) or Azure Data Studio. - Check the exact line number referenced in the error message output pane.
- Look specifically for
CONSTRAINTkeywords followed by a name starting with#, such asCONSTRAINT #PK_Orders.
Step 2: Correct the Constraint Naming Syntax
- Remove the leading number sign from the constraint name definition.
- Rename the constraint to follow standard SQL Server identifier rules (e.g., change
#PK_OrderstoPK_Orders). - If the name was dynamically generated via a variable (e.g.,
@ConstraintName = '#' + @TableName), edit the string concatenation logic to exclude the#character. - Ensure compliance with standard identifier rules outlined in SQL Server Books Online for regular identifiers.
Step 3: Validate Dynamic SQL and ORM Templates
- If using Entity Framework, Hibernate, or a custom migration tool on Windows Server 2025, check the migration template files for hardcoded
#symbols in constraint naming conventions. - Search your repository or script folder for the specific error string using PowerShell:
Select-String -Path "C:\Scripts\*.sql" -Pattern "CONSTRAINT #". - Update the template logic to generate standard alphanumeric names, typically using underscores (
_) instead of pound signs as separators.
Step 4: Re-execute the Corrected Script
- Open a new query window in SSMS connected to the target instance.
- Run the modified
CREATE TABLEorALTER TABLEscript against the Windows Server 2025 hosted database. - Confirm that the script completes with the “Command(s) completed successfully” message rather than Error 8166.
Alternative or Verification Steps
- Verify the Fix: Query
sys.objectswheretype_descmatches constraint types (e.g.,'DEFAULT_CONSTRAINT','FOREIGN_KEY_CONSTRAINT') to confirm the new constraint name exists in the schema without a leading pound sign. - Alternative Approach: If you require a mechanism to distinguish specific constraints programmatically, use a prefix like
tmp_orsys_instead of#, as these standard characters do not conflict with SQL Server’s temporary object parser.