Skip to content

SQL Server provider: JSON_VALUE should emit RETURNING nvarchar(4000) instead of RETURNING nvarchar(max) to avoid Azure SQL engine crash #37991

@knopa

Description

@knopa

Bug Description

When querying properties from native json columns, EF Core 10 generates
JSON_VALUE(..., '$.Property' RETURNING nvarchar(max)). This causes a fatal engine crash
on both Azure SQL and SQL Server 2025 when the query joins a wide table and selects
any column from it alongside JSON_VALUE RETURNING nvarchar(max).

Replacing RETURNING nvarchar(max) with RETURNING nvarchar(4000) fixes the crash entirely.

Since JSON_VALUE is already documented to return a maximum of nvarchar(4000) by default,
emitting RETURNING nvarchar(max) provides no practical benefit but triggers an engine bug
related to unbounded nvarchar(max) memory allocation when combined with wide table projections.

Error

Via application / remote connection:

Msg 40197, Level 20, State 12, Line 10
The service has encountered an error processing your request. Please try again. Error code 22002.
Msg 0, Level 20, State 0, Line 0
A severe error occurred on the current command. The results, if any, should be discarded.

Via direct SSMS connection (TCP):

Msg 10054, Level 20, State 0, Line 0
A transport-level error has occurred when receiving results from the server.
(provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)

Via direct SSMS connection (Shared Memory):

Msg 233, Level 20, State 0, Line 0
A transport-level error has occurred when receiving results from the server.
(provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)

Minimal Failing Query

SELECT
    [e].[Id],
    [w].[Id],                    -- any column from the wide joined table
    JSON_VALUE([e].[Data1], '$.Name'  RETURNING nvarchar(max)) AS [Name],
    JSON_VALUE([e].[Data1], '$.Email' RETURNING nvarchar(max)) AS [Email]
FROM [Entities] AS [e]
INNER JOIN [WideTable] AS [w] ON [e].[WideTableId] = [w].[Id]
WHERE [e].[ForeignKeyId] = 1

Where:

  • [e].[Data1] is a native json typed column (not nvarchar(max))
  • [WideTable] is a table with many columns (20+), regardless of which column is selected from it

Minimal Working Query

-- Option 1: replace nvarchar(max) with nvarchar(4000)
SELECT
    [e].[Id],
    [w].[Id],
    JSON_VALUE([e].[Data1], '$.Name'  RETURNING nvarchar(4000)) AS [Name],
    JSON_VALUE([e].[Data1], '$.Email' RETURNING nvarchar(4000)) AS [Email]
FROM [Entities] AS [e]
INNER JOIN [WideTable] AS [w] ON [e].[WideTableId] = [w].[Id]
WHERE [e].[ForeignKeyId] = 1

-- Option 2: remove the column selected from the wide table
SELECT
    [e].[Id],
    JSON_VALUE([e].[Data1], '$.Name'  RETURNING nvarchar(max)) AS [Name],
    JSON_VALUE([e].[Data1], '$.Email' RETURNING nvarchar(max)) AS [Email]
FROM [Entities] AS [e]
INNER JOIN [WideTable] AS [w] ON [e].[WideTableId] = [w].[Id]
WHERE [e].[ForeignKeyId] = 1

Exact Reproduction Conditions

Through extensive binary search testing, the crash requires all of the following:

Condition Required to crash
JSON_VALUE RETURNING nvarchar(max) ✅ Yes — nvarchar(4000) does not crash
INNER JOIN on a wide table (20+ columns) ✅ Yes — narrow tables or no JOIN do not crash
Any column selected from the wide joined table ✅ Yes — JOIN without selecting from it does not crash

Removing any one of these conditions prevents the crash.

Progression of Tests

Test Conditions Result
JSON_VALUE RETURNING nvarchar(max), no JOIN minimal ✅ OK
INNER JOIN wide table, no JSON_VALUE no JSON ✅ OK
INNER JOIN wide table + JSON_VALUE but no column selected from wide table partial ✅ OK
INNER JOIN wide table + JSON_VALUE RETURNING nvarchar(4000) + column from wide table bounded ✅ OK
INNER JOIN wide table + JSON_VALUE RETURNING nvarchar(max) + column from wide table full ❌ Crash

Schema

-- Table with native json columns
CREATE TABLE [Entities] (
    [Id]           int   NOT NULL,
    [WideTableId]  int   NOT NULL,   -- FK to wide table
    [ForeignKeyId] int   NOT NULL,
    [Data1]        json  NULL,       -- native json type
    [Data2]        json  NULL,       -- native json type
)

-- Wide table (20+ columns of various types)
CREATE TABLE [WideTable] (
    [Id]  int  NOT NULL,
    -- ... 20+ columns
)

Proposed Fix

EF Core should emit RETURNING nvarchar(4000) instead of RETURNING nvarchar(max)
for JSON_VALUE calls, since:

  1. JSON_VALUE already caps its return value at nvarchar(4000) by default —
    RETURNING nvarchar(max) provides no additional data capacity
  2. RETURNING nvarchar(max) triggers an engine bug on both Azure SQL and SQL Server 2025
    causing crashes when joining wide tables and selecting columns from them
  3. RETURNING nvarchar(4000) is functionally equivalent and does not trigger the crash

Workaround

Use a DbCommandInterceptor with a precise regex that targets only JSON_VALUE calls
to avoid accidentally replacing nvarchar(max) in other SQL contexts:

public class FixJsonValueInterceptor : DbCommandInterceptor
{
    // Targets only RETURNING nvarchar(max) inside JSON_VALUE calls
    private static readonly Regex JsonValueReturning = new(
        @"JSON_VALUE\(([^)]+)\s+RETURNING\s+nvarchar\(max\)\)",
        RegexOptions.Compiled
    );

    private static string Fix(string sql) =>
        JsonValueReturning.Replace(sql, "JSON_VALUE($1 RETURNING nvarchar(4000))");

    public override InterceptionResult<DbDataReader> ReaderExecuting(
        DbCommand command, CommandEventData eventData,
        InterceptionResult<DbDataReader> result)
    {
        command.CommandText = Fix(command.CommandText);
        return result;
    }

    public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(
        DbCommand command, CommandEventData eventData,
        InterceptionResult<DbDataReader> result,
        CancellationToken cancellationToken = default)
    {
        command.CommandText = Fix(command.CommandText);
        return ValueTask.FromResult(result);
    }
}

Register it:

options.UseSqlServer(connectionString)
       .AddInterceptors(new FixJsonValueInterceptor());

Environment

  • EF Core version: 10.x
  • Database provider: Microsoft.EntityFrameworkCore.SqlServer
  • Target framework: .NET 10
  • SQL Server 2025: 17.0.1105.2 (RTM-GDR, KB5077468) — ❌ crashes
  • Azure SQL: 12.0.2000.8 (RTM) — ❌ crashes
  • Column type: Native json (not nvarchar(max))

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions