[Bug] multipart/form-data is not processed on Kotlin/Native (CannotTransformContentToTypeException)
- Dominant language
- Kotlin
- Stars
- 14.5k
- Forks
- 1.3k
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 49
Description
## Description
When handling incoming HTTP requests with `Content-Type: multipart/form-data` on Kotlin/Native, the standard method `call.receiveMultipart()` fails to parse the request body. Client headers are formed correctly, and the server properly identifies the content type, but an exception is thrown during data reading.
The exact same code with identical dependencies works stably on JVM. The issue manifests exclusively on Native targets and has been reproduced across several consecutive library versions.
## Steps to reproduce
1. Start a Ktor server for Kotlin/Native target (linuxX64).
2. Create an endpoint:
```
put("/upload") {
val multipart = call.receiveMultipart()
// processing...
}
```
3. Send a PUT request with a valid header Content-Type: multipart/form-data; boundary=... and a form-data body.
4. Observe the error
### Expected behavior
The request is parsed successfully. receiveMultipart() returns an object containing all form parts and files, behaving identically to JVM.
### Actual behavior
An exception is thrown:
```
io.ktor.server.plugins.CannotTransformContentToTypeException: Cannot transform this request's content to io.ktor.http.content.MultiPartData
```
The server recognizes the correct Content-Type, but the standard receiver cannot complete processing the request body.
## Workaround found
The issue was bypassed by replacing the standard receiver with direct channel reading and manually initializing the instance of MultiPartData:
```
CIOMultipartDataBase(routingContext.call.coroutineContext, routingContext.call.receiveChannel(), routingContext.call.request.header(HttpHeaders.ContentType)!!, routingContext.call.request.contentLength(), formFieldLimit)
```
## Environment & Versions
Ktor version: 3.0.3, 3.4.0, 3.5.0 (issue persists across all tested versions)
Kotlin version: 2.3.21
Target: linuxX64
Client used for testing: Curl, Postman
Contributor guide
Research direction
Start by reproducing the linuxX64 server endpoint using call.receiveMultipart() with the multipart request described, then compare its Native path with the JVM behavior. Inspect the receiveMultipart flow and the CIOMultipartDataBase workaround shown in the issue. Done means valid multipart/form-data requests return form parts and files on Kotlin/Native without CannotTransformContentToTypeException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- kotlin
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100