RJ Garcia
05/20/2025, 4:07 PMval accessLogger = KotlinLogging.logger("access")
fun main() {
embeddedServer(Netty, configure = {
connectors.add(
EngineConnectorBuilder().apply {
host = "127.0.0.1"
port = 8080
},
)
connectionGroupSize = 1
workerGroupSize = 1
callGroupSize = 1
}) {
install(
createApplicationPlugin("CallLogging") {
on(ResponseSent) { call ->
try {
val values = call.response.headers.allValues()
accessLogger.info { "headers: $values" }
} catch (e: Exception) {
accessLogger.atError {
cause = e
message = "allValues failed"
}
}
}
},
)
routing {
get("/1") {
call.respond(HttpStatusCode.NoContent)
}
}
}.start(wait = true)
}
• Most of the time each request will print: headers: [Content-Length=[0]]
.
• very few times, it'll print headers: []
• And very few times, it'll actually throw an exception like:
java.util.NoSuchElementException: null
at io.netty.handler.codec.DefaultHeaders$HeaderIterator.next(DefaultHeaders.java:1291)
at io.netty.handler.codec.DefaultHeaders$HeaderIterator.next(DefaultHeaders.java:1278)
at io.netty.handler.codec.HeadersUtils$StringEntryIterator.next(HeadersUtils.java:123)
at io.netty.handler.codec.HeadersUtils$StringEntryIterator.next(HeadersUtils.java:109)
at io.ktor.server.netty.http1.NettyHttp1ApplicationResponse$headers$1.getEngineHeaderNames(NettyHttp1ApplicationResponse.kt:125)
at io.ktor.server.response.ResponseHeaders.allValues(ResponseHeaders.kt:50)
at com.yahoo.finance.ypf.gateway.ApplicationKt.main$lambda$4$lambda$2$lambda$1(Application.kt:50)
This only seems to happen with the NoContent status code, i'm able to replicate this pretty simply with the plow tool:
plow -c 1 <http://localhost:8080/1>
Any ideas on why reading the response headers on the ResponseSent hook for NoContent responses might behave this way?Aleksei Tirman [JB]
05/21/2025, 12:36 PMRJ Garcia
05/21/2025, 1:18 PMconnectionGroupSize = 1
workerGroupSize = 1
callGroupSize = 1
RJ Garcia
05/21/2025, 3:11 PMRJ Garcia
05/21/2025, 3:12 PMRJ Garcia
05/21/2025, 3:37 PMAleksei Tirman [JB]
05/22/2025, 7:49 AM