undici: Sending a DELETE request with "Content-Length: 0" fails with a RequestContentLengthMismatchError

Bug Description

Sending a DELETE request with “content-length: 0” fails with a RequestContentLengthMismatchError.

The specification says “A user agent SHOULD NOT send a Content-Length header field when the request message does not contain a payload body and the method semantics do not anticipate such a body”, but according to RFC 2119, “SHOULD NOT” means “NOT RECOMMENDED”, so it’s not reasonable to fail a request for this reason.

Even if the Content-Length header “MUST NOT” be sent, the current implementation would still be problematic:

  1. A better behavior could be removing the header instead of failing the request.
  2. The request only fails when Content-Length is set to zero, but not when it is not zero and matches the length of the body. Note that the DELETE method does not anticipate a body.
  3. The error message is unhelpful. It says “Request body length does not match content-length header” instead of “Content-Length should not be set for the DELETE method”.

Reproducible By

fetch('https://example.com', { method: 'DELETE', headers: { 'content-length': '0' } })

Expected Behavior

The request succeeds, either as it is or with the Content-Length header removed.

Logs & Screenshots

> Uncaught TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11413:11) {
  cause: RequestContentLengthMismatchError: Request body length does not match content-length header
      at write (node:internal/deps/undici/undici:9907:41)
      at _resume (node:internal/deps/undici/undici:9885:33)
      at resume (node:internal/deps/undici/undici:9787:7)
      at connect (node:internal/deps/undici/undici:9776:7) {
    code: 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH'
  }
}

Environment

Reproducible on both Node v18.15.0 and v19.8.1

Additional Context

Related codes:

https://github.com/nodejs/undici/blob/5f3b8e16a9aa33fe72d640fe271d8e7a5748321a/lib/client.js#L1333-L1366

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 8
  • Comments: 19 (14 by maintainers)

Most upvoted comments

I encountered this error as well. Using tRPC with Next.JS:

 TRPCClientError: fetch failed
    at TRPCClientError.from (file:///var/task/node_modules/@trpc/client/dist/transformResult-6fb67924.mjs:13:16)
    at file:///var/task/node_modules/@trpc/client/dist/links/httpBatchLink.mjs:211:64 {
  meta: undefined,
  shape: undefined,
  data: undefined,
  [cause]: TypeError: fetch failed
      at Object.fetch (node:internal/deps/undici/undici:14062:11) {
    cause: RequestContentLengthMismatchError: Request body length does not match content-length header
        at AsyncWriter.end (node:internal/deps/undici/undici:9704:19)
        at writeIterable (node:internal/deps/undici/undici:9614:16) {
      code: 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH'
    }
  }
}

What is the realistic scenario where this is a problem?

I’m using Nuxt, which is using Nitro, whose proxy is based on node-http-proxy. And the problem comes from this code:

https://github.com/http-party/node-http-proxy/blob/9b96cd725127a024dabebec6c7ea8c807272223d/lib/http-proxy/passes/web-incoming.js#L34-L40

node-http-proxy is not actively maintained, and it cost me a few hours to find where the bug was. It’s certainly a bug of node-http-proxy in my case, but I just think it doesn’t worth the effort (to locate and) to fix the bug when the Content-Length header is mistakenly added somewhere.

Moved to axios and the request seems to be working now. Will report back if there are further issues.

no, it’s an integer (the code in the linked issue only checks for 0)

Should the server ignore content-length when it receives a DELETE request?

content-length is removed on redirect in fetch, this bug would also affect undici.request

I’m aware it affects undici.request, however I wouldn’t consider it a bug per se in that context. Might be different for fetch of the spec says to remove it.