Skip to content

Matched requests that contain invalid header values (eg with emoji) return a 502 to the client #2374

@Laura7089

Description

@Laura7089

The expected behaviour of this should be to return a 4XX error to the client.

Reproducing

Reproduced against the Basic sample on tag 24.1.0 with:

curl -X GET -v 'http://localhost:5555/ocelot/posts/askdj' \
  --header 'Accept: */*' \
  --header 'skull: 💀'

Prints:

Note: Unnecessary use of -X or --request, GET is already inferred.
* Host localhost:5555 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:5555...
* Established connection to localhost (::1 port 5555) from ::1 port 57284
* using HTTP/1.x
> GET /ocelot/posts/askdj HTTP/1.1
> Host: localhost:5555
> User-Agent: curl/8.19.0
> Accept: */*
> skull: 💀
>
* Request completely sent off
< HTTP/1.1 502 Bad Gateway
< Content-Length: 0
< Date: Mon, 30 Mar 2026 14:01:37 GMT
< Server: Kestrel
<
* Connection #0 to host localhost:5555 left intact

Logs

The logs shed some light:

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET http://localhost:5555/ocelot/posts/askdj - - -
dbug: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      Ocelot pipeline started
dbug: Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      Upstream URL path: /ocelot/posts/askdj
dbug: Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      Downstream templates: /todos/{id}
info: Ocelot.RateLimiting.RateLimitingMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      Rate limiting is disabled for route '/ocelot/posts/{id}' via the EnableRateLimiting option.
info: Ocelot.Authentication.AuthenticationMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      No authentication is required for the path '/ocelot/posts/askdj' in the route /ocelot/posts/{id}.
dbug: Ocelot.Authorization.AuthorizationMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      No authorization needed for the route: /ocelot/posts/{id}
dbug: Ocelot.DownstreamUrlCreator.DownstreamUrlCreatorMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      Downstream URL: https://jsonplaceholder.typicode.com/todos/askdj
info: Ocelot.Requester.Middleware.HttpRequesterMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      102 unknown status code of request URI: 
dbug: Ocelot.Requester.Middleware.HttpRequesterMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      IHttpRequester returned an error, setting pipeline error
warn: Ocelot.Responder.Middleware.ResponderMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      ResponderMiddleware found 1 error ->
      ConnectionToDownstreamServiceError: Error connecting to downstream service, exception: System.Net.Http.HttpRequestException: Request headers must contain only ASCII characters.
         at System.Net.Http.HttpConnection.<WriteString>g__ThrowForInvalidCharEncoding|55_0()
         at System.Net.Http.HttpConnection.WriteString(String s, Encoding encoding)
         at System.Net.Http.HttpConnection.WriteHeaderCollection(HttpHeaders headers, String cookiesFromContainer)
         at System.Net.Http.HttpConnection.WriteHeaders(HttpRequestMessage request)
         at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
         at System.Net.Http.HttpConnection.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
         at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
         at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
         at Ocelot.Requester.TimeoutDelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /home/laura/scratch_pad/Ocelot/src/Ocelot/Requester/TimeoutDelegatingHandler.cs:line 30
         at Ocelot.Requester.MessageInvokerHttpRequester.GetResponse(HttpContext httpContext) in /home/laura/scratch_pad/Ocelot/src/Ocelot/Requester/MessageInvokerHttpRequester.cs:line 29
      Setting error response for request: GET /ocelot/posts/askdj
dbug: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0]
      RequestId: 0HNKECIQOAUK4:00000001, PreviousRequestId: -
      Ocelot pipeline finished
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/1.1 GET http://localhost:5555/ocelot/posts/askdj - 502 0 - 58.9493ms

Metadata

Metadata

Assignees

Labels

CoreOcelot Core related or system upgrade (not a public feature)RFC-7230RFC 7230 standard titled "Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing"RoutingOcelot feature: RoutingbugIdentified as a potential bugmergedIssue has been merged to dev and is waiting for the next release

Type

No fields configured for Bug.

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions