JSON log format pairs ILogger message template placeholders with state values by position, garbling ASP.NET Core hosting logs
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 70/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- aws, csharp
- Domain
- backend, observability-sre
Research direction
Read Libraries/src/Amazon.Lambda.Logging.AspNetCore/LambdaILogger.cs and Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/Logging/JsonLogMessageFormatter.cs, then run the minimal ASP.NET Core reproduction with JSON logging. Done means the Request starting record resolves each JSON property by its placeholder name and the rendered message is no longer shifted.
Written by the indexing model from the issue text.
Description
Describe the bug
When a function uses LoggingConfig.LogFormat: JSON and bridges Microsoft.Extensions.Logging.ILogger to the Lambda logging API via Amazon.Lambda.Logging.AspNetCore, structured log events can come out with their JSON properties holding the wrong values (each property shifted to a neighboring placeholder's value).
Root cause, as far as I can tell, is a combination of two behaviors:
LambdaILoggerextracts the message template from{OriginalFormat}and collects the state values in state enumeration order (LambdaILogger.cs).JsonLogMessageFormatterthen pairs template placeholders with arguments strictly by position (JsonLogMessageFormatter.cs).
The Microsoft.Extensions.Logging contract is that placeholders are resolved by name against the state key/value pairs; nothing guarantees that state enumeration order matches placeholder order. The most prominent violator ships in ASP.NET Core itself: HostingRequestStartingLog enumerates its state as Protocol, Method, ContentType, ContentLength, Scheme, Host, PathBase, Path, QueryString, while its template is:
Request starting {Protocol} {Method} {Scheme}://{Host}{PathBase}{Path}{QueryString} - {ContentType} {ContentLength}
So every Request starting log line of every ASP.NET Core app running on Lambda with JSON log format is silently garbled from the third placeholder on.
Regression Issue
- Select this option if this issue appears to be a regression.
Expected Behavior
Template placeholders resolved by name, as with every other Microsoft.Extensions.Logging sink:
{
"message": "Request starting HTTP/1.1 DELETE https://api.example.com/events/123?preserve=true - application/json 0",
"Method": "DELETE",
"Scheme": "https",
"Host": "api.example.com",
"Path": "/events/123",
"QueryString": "?preserve=true",
"ContentType": "application/json",
"ContentLength": 0
}
Current Behavior
Actual CloudWatch log record (values anonymized). Note Scheme holding the content type, Host holding the content length, Path holding the host, ContentType holding the path, etc.:
{
"timestamp": "2026-07-04T22:43:57.529Z",
"level": "Information",
"requestId": "188cbe50-087d-4465-acf4-d4a6067ef0da",
"message": "Request starting {Protocol} DELETE application/json://0httpsapi.example.com - /events/123 ?preserve=true",
"Method": "DELETE",
"Scheme": "application/json",
"Host": 0,
"PathBase": "https",
"Path": "api.example.com",
"QueryString": "",
"ContentType": "/events/123",
"ContentLength": "?preserve=true"
}
Each placeholder received the state value at the same index instead of the value with the matching name ({Scheme} ← ContentType, {Host} ← ContentLength, {PathBase} ← Scheme, ...). The rendered message is garbled the same way.
Reproduction Steps
Minimal ASP.NET Core app:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi);
builder.Logging.ClearProviders();
builder.Logging.AddLambdaLogger();
var app = builder.Build();
app.MapGet("/", () => "ok");
app.Run();
Deploy behind API Gateway with:
LoggingConfig:
LogFormat: JSON
Invoke any endpoint and inspect the Request starting record in CloudWatch: the Scheme, Host, PathBase, Path, QueryString, ContentType and ContentLength properties are shifted as shown above.
Possible Solution
Either:
- In
LambdaILogger(JSON branch): parse the placeholder names from{OriginalFormat}and emit the arguments in placeholder order, resolving each one by key against the state; or - In
JsonLogMessageFormatter: when arguments come from anILoggerstate, match them to placeholders by name instead of by position.
Additional Information/Context
Any ILogger event whose state enumeration order differs from its template placeholder order is affected — ASP.NET Core hosting logs are just the guaranteed-out-of-the-box case. Logs written through the standard LoggerExtensions/LoggerMessage paths happen to be unaffected because FormattedLogValues keeps both orders aligned, which is probably why this went unnoticed.
AWS .NET SDK and/or Package version used
Amazon.Lambda.AspNetCoreServer 10.1.1
Amazon.Lambda.AspNetCoreServer.Hosting 2.1.0
Amazon.Lambda.Logging.AspNetCore 5.0.0
Amazon.Lambda.Core 3.1.0
Targeted .NET Platform
.NET 10 (managed dotnet10 runtime)
Operating System and version
Amazon Linux 2023 (Lambda managed runtime)
- Dominant language
- C#
- Stars
- 1.7k
- Forks
- 503
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 21
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from aws/aws-lambda-dotnet
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
aws/aws-lambda-dotnet#2571 · 1 comment ·
-
bug module/aspnetcore-support p2 queued
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
aws/aws-lambda-dotnet#1123 · 4 comments · 1 reaction ·
-
feature-request
Difficulty 4/5 3-5 days Newbie friendliness 68/100
aws/aws-lambda-dotnet#2572 · 1 comment ·
-
feature-request needs-triage
Difficulty 4/5 3-5 days Newbie friendliness 48/100
aws/aws-lambda-dotnet#2551 · 1 comment ·
-
feature-request needs-review
Difficulty 5/5 Over a week Newbie friendliness 35/100
aws/aws-lambda-dotnet#2519 ·
All issues in aws/aws-lambda-dotnet
Similar issues
-
type/automation type/tech-debt
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
t/bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
ci-failure-cause test-failure
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
area:auth FE mvp P3
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
klasolsson81/jobbliggaren#1788 ·