[Bug]: kernel download hangs forever when the server stops sending

Abierto Apto para principiantes
#2,327 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@devops-thiago ya está trabajando en esto.

Desde el 1/10/2026.

  • #2331 de @devops-thiago — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
84/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
swift
Área
networking

Línea de trabajo

Comienza en Sources/Services/ContainerAPIService/Client/FileDownloader.swift, en la configuración del tiempo de espera del cliente HTTP. Revisa el comportamiento del tiempo de espera de lectura inactiva de AsyncHTTPClient y, después, prueba la descarga contra el servidor stall.py proporcionado. El trabajo estará terminado cuando una descarga del kernel atascada devuelva un error que indique la URL en lugar de esperar indefinidamente, mientras las transferencias lentas siguen siendo compatibles.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

I have done the following
  • I have searched the existing issues
  • If possible, I've reproduced the issue using the 'main' branch of this project
Steps to reproduce

Serve a kernel archive from a server that answers the request, sends part of the body and then goes quiet without closing the connection. A few lines of Python do it:

# stall.py
import socket
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("127.0.0.1", 8099))
s.listen(1)
c, _ = s.accept()
c.recv(65536)
c.sendall(b"HTTP/1.1 200 OK\r\nContent-Length: 100000000\r\n\r\n" + b"x" * 1000)
while True:
    c.recv(1)
python3 stall.py &
container system kernel set --arch arm64 --binary boot/vmlinux \
  --tar http://127.0.0.1:8099/kernel.tar \
  --digest sha256:0000000000000000000000000000000000000000000000000000000000000000

The command prints nothing and does not return. I checked after 30, 60, 90 and 120 seconds, and it was still running each time:

$ ps -o pid,etime,command -p 22848
  PID ELAPSED COMMAND
22848   02:01 container system kernel set --arch arm64 --binary boot/vmlinux --tar http://127.0.0.1:8099/kernel.tar --digest sha256:000...
$ lsof -nP -iTCP:8099 -sTCP:ESTABLISHED
COMMAND     PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
container  2291 thiago   16u  IPv4 0x2f0bf36d39eb4ebb      0t0  TCP 127.0.0.1:52365->127.0.0.1:8099 (ESTABLISHED)
Python    22776 thiago    4u  IPv4 0xbfe38cab71c4f742      0t0  TCP 127.0.0.1:8099->127.0.0.1:52365 (ESTABLISHED)

PID 2291 is container-apiserver, which holds the connection open and is waiting for data that never comes.

container system kernel set --recommended downloads the same way, so a connection that stalls partway through the real archive behaves identically.

Problem description

FileDownloader builds its HTTP client with no read timeout:

https://github.com/apple/container/blob/0a48a1bd/Sources/Services/ContainerAPIService/Client/FileDownloader.swift#L64-L69

// for large file downloads we keep a generous connect timeout, and
// no read timeout since download durations can vary
httpConfiguration.timeout = HTTPClient.Configuration.Timeout(
    connect: .seconds(30),
    read: .none
)

The comment is about total duration, but a read timeout in AsyncHTTPClient is an idle timeout. It starts over each time data arrives, so a slow download is not affected. With .none, a server or proxy that accepts the connection and then stops sending leaves the request waiting indefinitely, and the kernel install with it.

An idle timeout of 30 seconds would turn that into an error that names the URL. This is separate from resuming interrupted downloads (#2294).

I reproduced this on the 1.5.0 release. The code is unchanged on main at 0a48a1b, and a test against that code that downloads from the same kind of server is still waiting after 8 seconds.

Environment
  • OS: macOS 26.6.2 (25G83)
  • Xcode: 26.6 (17F113)
  • Container: 1.5.0 (Homebrew)
Code of Conduct
  • I agree to follow this project's Code of Conduct
Lenguaje dominante
Swift
Estrellas
51.1k
Forks
1.8k
Merge medio
2 d 10 h
PR fusionados (30 d)
37

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de apple/container

Todos los issues de apple/container

Issues similares

Más issues de Swift

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.