Troubleshooting Guide: SQL Server Error 10509 — Plan Guide Creation Failure
Why This Error Happens
Error 10509 occurs when the Transact-SQL statement supplied to sp_create_plan_guide (via @stmt or @module_or_batch combined with @statement_start_offset) does not match exactly, character-for-character, with the statement SQL Server expects to bind the plan guide to. This mismatch is commonly caused by extra whitespace, inconsistent line breaks, collation differences, or the use of unsupported constructs (such as certain USE statements, CTEs in the wrong context, or statements that reference objects in a way the optimizer cannot validate). It can also happen if the @statement_start_offset points to the wrong byte position within the batch, or if the plan guide type (OBJECT, SQL, or TEMPLATE) is incompatible with the statement structure provided.
Step-by-Step Resolution Guide
Step 1: Validate the Exact Text of the Target Statement
- Extract the statement directly from
sys.dm_exec_sql_textorsys.dm_exec_query_statsrather than retyping it manually. - Ensure there are no trailing spaces, tab characters, or mismatched line-ending styles (CRLF vs LF) between the captured text and the
@stmtparameter. - Confirm the statement does not include a semicolon or batch terminator unless the original batch did.
Step 2: Verify Plan Guide Type and Offset Alignment
- If using
@type = 'OBJECT', confirm the@module_or_batchname matches an existing stored procedure, function, or trigger exactly, including schema prefix (e.g.,dbo.usp_GetOrders). - If using
@statement_start_offset, recalculate the byte offset usingDATALENGTH()on the preceding text in Unicode, since SQL Server stores batch text asnvarchar. - Run the statement in isolation using
SET SHOWPLAN_XML ONto confirm it compiles independently without errors.
Step 3: Check for Unsupported T-SQL Constructs
- Remove or isolate statements containing
RECEIVE,READTEXT,INSERT...EXEC, or multi-statement table-valued function calls, as these are ineligible for plan guides. - If the statement includes a Common Table Expression (CTE), ensure the plan guide is created against the full CTE-containing statement, not just the inner
SELECT. - On Windows Server 2025 / Windows 11 hosts, confirm the SQL Server 2025 instance has the latest Cumulative Update applied, since several plan guide parsing fixes are delivered via CU patches (check via
SELECT @@VERSION).
Step 4: Recreate the Plan Guide Using spcreateplan_guide Safely
- Use the
OBJECTtype when targeting stored procedures instead of manually supplying offsets, as it eliminates offset mismatch errors entirely. - Example:
EXEC sp_create_plan_guide
@name = N'PG_FixedGuide',
@stmt = N'SELECT * FROM dbo.Orders WHERE CustomerID = @CustomerID',
@type = N'OBJECT',
@module_or_batch = N'dbo.usp_GetOrders',
@params = NULL,
@hints = N'OPTION (RECOMPILE)';
- Drop any failed or orphaned plan guide attempts first using
sp_control_plan_guide @operation = N'DROP', @name = N'PG_FixedGuide'.
Alternative or Verification Steps
- Query
sys.plan_guidesand check theis_disabledandscope_type_desccolumns to confirm the guide was created successfully and is active. - If manual
@stmtmatching continues to fail, use Plan Guide from existing cached plan viasp_create_plan_guide_from_handle, which copies the exact query text and offset automatically fromsys.dm_exec_query_stats, bypassing manual transcription errors entirely.