# Troubleshooting OpenEnv WebSocket Connection Timeouts and Message Size Limits

> Fix OpenEnv WebSocket timeouts and message size limits by tuning connect timeout, message timeout, and max message size settings for smoother connections and larger data transfers.

- Repository: [Hugging Face/OpenEnv](https://github.com/huggingface/OpenEnv)
- Tags: troubleshooting
- Published: 2026-06-14

---

**To resolve OpenEnv WebSocket issues, increase `connect_timeout_s` for slow handshakes, adjust `message_timeout_s` for delayed responses, or raise `max_message_size_mb` when observations exceed the default 100 MiB limit.**

OpenEnv uses persistent WebSocket connections managed by the `EnvClient` class to communicate with environment servers. When working with high-resolution observations or slow network conditions, you may encounter OpenEnv WebSocket connection timeouts or message size errors that halt your agent's execution. This guide explains how to diagnose and fix these issues using the exact parameters and source locations in the `huggingface/OpenEnv` repository.

## Understanding the Connection Flow

The `EnvClient` class in [`src/openenv/core/env_client.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/env_client.py) handles all WebSocket communication. It converts HTTP URLs to WebSocket endpoints via `convert_to_ws_url` in [`src/openenv/core/utils.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/utils.py) (lines 48-50), then establishes a persistent connection using `websockets.asyncio.client.connect`. Three specific parameters control timeout and size behavior: `open_timeout` for the initial handshake, `self._message_timeout` for response windows, and `max_size` for payload limits.

## Diagnosing Connection Timeouts

Connection timeouts in OpenEnv manifest in two distinct phases: during the initial handshake and while waiting for message responses.

### Initial Handshake Timeout

The `EnvClient.connect()` method passes an `open_timeout` argument to `ws_connect` (lines 104-108 in [`src/openenv/core/env_client.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/env_client.py)). The default is 10 seconds. If the server is unreachable, DNS resolution is slow, or proxies interfere, the connection fails before the WebSocket handshake completes.

### Message Response Timeout

After connecting, `EnvClient._receive()` wraps each read in `asyncio.wait_for` using `self._message_timeout` (lines 140-142). This defaults to 60 seconds. Heavy computations or deadlocks in the environment server that exceed this window trigger a timeout error on the client side.

## Handling Message Size Limits

Large observations such as high-resolution screenshots or DOM snapshots can exceed the default 100 MiB limit. In `EnvClient.__init__()`, the `max_message_size_mb` parameter is converted to bytes and stored as `self._max_message_size` (lines 152-157), then passed as `max_size` to `ws_connect`. When payloads exceed this limit, the WebSocket connection terminates abruptly.

## Configuration and Troubleshooting Steps

Follow these steps to resolve WebSocket issues based on the failure mode:

- **Verify URL conversion**: Ensure your base URL uses the correct scheme. `convert_to_ws_url` in [`src/openenv/core/utils.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/utils.py) automatically rewrites `http://` to `ws://`, but typos in the domain or port cause immediate DNS errors and connection timeouts.

- **Check localhost proxy bypass**: For local development, OpenEnv temporarily adds `localhost,127.0.0.1` to the `NO_PROXY` environment variable (lines 180-194) to prevent proxy interception. For remote servers, manually configure `NO_PROXY` to avoid idle connection drops.

- **Increase connection timeout**: When the server needs more time to accept connections, pass a higher `connect_timeout_s` value to the constructor.

- **Raise message timeout**: For computationally expensive environment steps, increase `message_timeout_s` to allow longer response windows.

- **Expand message size limits**: When transmitting large observations, increase `max_message_size_mb` to accommodate the payload.

## Practical Code Examples

Here are complete examples showing how to configure the `GenericEnvClient` with adjusted limits.

### Basic Usage with Increased Timeouts

```python
from openenv.core.env_client import GenericEnvClient

# Initialise a client with generous limits

client = GenericEnvClient(
    base_url="http://localhost:8000",   # will be converted to ws:// automatically

    connect_timeout_s=20.0,             # 20 seconds handshake timeout

    message_timeout_s=180.0,            # 3 minutes per response

    max_message_size_mb=300.0,          # allow up to 300 MiB per message

)

async def run_episode():
    async with client:               # ensures connect() / close()

        # Reset the environment

        state = await client.reset()
        # Step until done

        while not state.done:
            # Example action – replace with your policy

            action = {"code": "print('step')"}
            state = await client.step(action)
        print("Episode finished")

```

### Configuration for Remote Production Servers

```python
client = GenericEnvClient(
    base_url="https://my-openenv-prod.com",
    connect_timeout_s=60.0,
    message_timeout_s=300.0,
    max_message_size_mb=1024.0,   # 1 GiB – useful for high-resolution video frames

)

```

### Handling Connection Timeout Errors

```python
try:
    await client.connect()
except ConnectionError as exc:
    # Log, retry, or fall back to a different endpoint

    print(f"WebSocket connect failed: {exc}")

```

## Summary

- Connection timeouts occur in `EnvClient.connect()` (10s default) or `EnvClient._receive()` (60s default), controlled by `connect_timeout_s` and `message_timeout_s` respectively.
- Message size limits default to 100 MiB and are configured via `max_message_size_mb` in the constructor.
- Localhost connections automatically bypass proxies via `NO_PROXY` manipulation (lines 180-194), but remote servers require manual configuration.
- Always verify URL formatting using `convert_to_ws_url` in [`src/openenv/core/utils.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/utils.py) to prevent DNS-related connection failures.

## Frequently Asked Questions

### Why does my OpenEnv connection fail immediately with a timeout?

Immediate timeouts typically indicate that `EnvClient.connect()` cannot complete the WebSocket handshake within the default 10-second `open_timeout` window. Check that the server is running, the URL is correct (verify `convert_to_ws_url` in [`src/openenv/core/utils.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/utils.py)), and no firewall or proxy is blocking the connection on the specified port.

### How do I handle large screenshots or video frames in OpenEnv?

Increase the `max_message_size_mb` parameter when constructing `GenericEnvClient`. The default 100 MiB limit is enforced in [`src/openenv/core/env_client.py`](https://github.com/huggingface/OpenEnv/blob/main/src/openenv/core/env_client.py) (lines 152-157) where the value is converted to bytes and passed as `max_size` to `ws_connect`. For high-resolution video, values up to 1024 MiB (1 GiB) are supported.

### What causes "message timeout" errors during environment steps?

Message timeouts originate in `EnvClient._receive()` (lines 140-142) where `asyncio.wait_for` enforces `self._message_timeout` (default 60 seconds). This occurs when the environment server takes too long to compute observations or experiences a deadlock. Increase `message_timeout_s` or optimize the server-side computation.

### Does OpenEnv support proxy servers for WebSocket connections?

OpenEnv automatically adds `localhost,127.0.0.1` to the `NO_PROXY` environment variable (lines 180-194) to prevent local proxy interception. For remote servers, you must manually configure `NO_PROXY` or ensure your proxy supports WebSocket upgrade connections to avoid intermittent timeouts.