Skip to content

Using a logger causes infinite spam logs when file descriptor limit is reached in HTTP::Server #15862

Open
@syeopite

Description

@syeopite

Bug Report

Using the logger to print any kind of message (Log.setup doesn't seem to trigger this) results in the HTTP::Server infinitely spamming logs whenever the file descriptor limit is reached.

require "http/server"

Log.info { "test" }

server = HTTP::Server.new do | context |
  loop do
    context.response.puts ":keepalive #{Time.utc.to_unix}"
    context.response.puts
    context.response.flush

    sleep 2.seconds
  end
end

server.listen 12345

Results in

2025-06-01T19:01:40.364067Z  ERROR - http.server: Error while connecting a new socket
accept: Too many open files (Socket::Error)
...

2025-06-01T19:01:40.364070Z  ERROR - http.server: Error while connecting a new socket
accept: Too many open files (Socket::Error)
...

2025-06-01T19:01:40.364074Z  ERROR - http.server: Error while connecting a new socket
accept: Too many open files (Socket::Error)
...
and so on

When the logger isn't present, the program just crashes instantly and only two exceptions are logged.

Crystal 1.16.0 (2025-04-11)

LLVM: 19.1.7
Default target: x86_64-pc-linux-gnu

Here's a simple script that can trigger this bug in the above code

Simple request to spam request a server to trigger this
require "http"
require "wait_group"

ADDRESS = URI.parse("http://localhost:12345")

def make_client
  client = HTTP::Client.new(ADDRESS)
  client.get("/") do | response |
    until response.body_io.closed?
      response.body_io.gets
    end
  end
ensure
  client.try &.close
end

5.times do
  clients_opened = [] of HTTP::Client
  # Create in batches as to not trigger our own file descriptor limit
  250.times { spawn { make_client } }
end

sleep

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:bugA bug in the code. Does not apply to documentation, specs, etc.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions