FastAPI WebSocket returns HTTP 404 on Spaces

Hello,

I am experiencing a persistent issue with deploying a FastAPI application with a WebSocket endpoint on Hugging Face Spaces. All WebSocket connection attempts fail with server rejected WebSocket connection: HTTP 404, while standard HTTP GET requests to the same application work perfectly.

This suggests that the request is being blocked by the proxy before it reaches the application container.

Space URL: https://efm-ua-docgem-stt-poc.hf.space/

Problem Details:

  • A GET request to https://efm-ua-docgem-stt-poc.hf.space/ correctly returns a 200 OK with a JSON response.

  • A WebSocket connection attempt to wss://efm-ua-docgem-stt-poc.hf.space/ws fails with a 404 error.

  • The application logs show the successful GET request but never show any trace of the WebSocket connection attempt, confirming it does not reach the Uvicorn server.

  • The issue persists regardless of the WebSocket endpoint path (/, /ws, /queue/join).

Here is a minimal reproducible example that demonstrates the problem:

  1. Dockerfile
    FROM tiangolo/uvicorn-gunicorn:python3.12

ENV GRADIO_SERVER_PORT=7860
ENV GRADIO_SERVER_NAME=0.0.0.0

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY ./main.py .

EXPOSE 7860

CMD [“uvicorn”, “main:app”, “–host”, “0.0.0.0”, “–port”, “7860”, “–proxy-headers”]

  1. requirements.txt
    fastapi
    uvicorn[standard]
    websockets

import logging
from fastapi import FastAPI, WebSocket, WebSocketDisconnect

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(name)

app = FastAPI()

@app.get(“/”)
async def read_root():
logger.info(“Received GET request to root.”)
return {“status”: “ok”, “message”: “Worker is running. WebSocket is at /ws”}

@app.websocket(“/ws”)
async def websocket_endpoint(websocket: WebSocket):
logger.info(f"WebSocket connection attempt from {websocket.client}“)
await websocket.accept()
logger.info(“WebSocket connection accepted.”)
try:
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Echo: {data}”)
except WebSocketDisconnect:
logger.info(“Client disconnected.”)

Could you please advise if there is a specific configuration required to allow WebSocket traffic on a non-Gradio FastAPI application?

1 Like

Perhaps this case?

server rejected WebSocket connection: HTTP 404 :slightly_frowning_face:

1 Like

I wonder if this bug (?) is also occurring in FastAPI…:thinking: