Skip to content

POST Requests with Streaming Bodies Fail with 500 Error #98

@i-icc

Description

@i-icc

When sending POST requests with a request body (e.g., gRPC/Connect requests) through the Container class, the request fails with a 500 error. This occurs because the containerFetch method does not include the duplex: "half" option when forwarding requests with streaming bodies.

Steps to Reproduce

  1. Set up a container running a gRPC/Connect server (or any server accepting POST with body)
  2. Send a POST request with a JSON body through the Container class:
curl -X POST http://hoge.workers.dev/health \
  -H "Content-Type: application/json" \
  -d '{}'

ex

curl -v -X POST http://hoge.workers.dev/proto.hoge.v1.hogeService/HealthCheck \
  -H "Content-Type: application/json" \
  -d '{}'
Note: Unnecessary use of -X or --request, POST is already inferred.
* Host hoge.workers.dev:80 was resolved.
* IPv6: xxx,xxx
* IPv4: xxx.xxx.xxx.xxx, xxx.xxx.xxx.xxx
*   Trying [xxx]:80...
* Connected to hoge.workers.dev (xxx) port 80
> POST /proto.hoge.v1.hogeService/HealthCheck HTTP/1.1
> Host: hoge.workers.dev
> User-Agent: curl/8.7.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 2
> 
* upload completely sent off: 2 bytes
< HTTP/1.1 500 Internal Server Error
< Date: Wed, 01 Oct 2025 14:13:39 GMT
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 42
< Connection: keep-alive
< Vary: accept-encoding
< Report-To: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"hoge"}]}
< Nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
< Server: cloudflare
< CF-RAY: 987c8fd6bf0eafd3-NRT
< alt-svc: h3=":443"; ma=86400
< 
* Connection #0 to host hoge.workers.dev left intact
Container suddenly disconnected, try again%  

The container log is normal, but the worker is not receiving it correctly.

Suspicious code

In src/lib/container.ts at line 707:

const res = await tcpPort.fetch(containerUrl, request);

When a Request object with a body is passed to fetch(), the body property is a ReadableStream. According to the Fetch API specification, when the request body is a stream, the duplex property must be explicitly set to "half".

(English is not my first language so I apologize if I didn't capture the nuances.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions