How to fix Error 10509 on Windows Server 2025 / Windows 11

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_text or sys.dm_exec_query_stats rather 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 @stmt parameter.
  • 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_batch name 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 using DATALENGTH() on the preceding text in Unicode, since SQL Server stores batch text as nvarchar.
  • Run the statement in isolation using SET SHOWPLAN_XML ON to 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 OBJECT type 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_guides and check the is_disabled and scope_type_desc columns to confirm the guide was created successfully and is active.
  • If manual @stmt matching continues to fail, use Plan Guide from existing cached plan via sp_create_plan_guide_from_handle, which copies the exact query text and offset automatically from sys.dm_exec_query_stats, bypassing manual transcription errors entirely.