Vincent Chéry
08/06/2025, 2:40 PMTraceback (most recent call last):
File "/opt/pysetup/.venv/lib/python3.13/site-packages/prefect/cli/_utilities.py", line 44, in wrapper
return fn(*args, **kwargs)
File "/opt/pysetup/.venv/lib/python3.13/site-packages/prefect/cli/_types.py", line 156, in sync_fn
return asyncio.run(async_fn(*args, **kwargs))
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/asyncio/runners.py", line 195, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File "/usr/local/lib/python3.13/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/usr/local/lib/python3.13/asyncio/base_events.py", line 725, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File "/opt/pysetup/.venv/lib/python3.13/site-packages/prefect/cli/flow_run.py", line 395, in execute
await runner.execute_flow_run(id)
File "/opt/pysetup/.venv/lib/python3.13/site-packages/prefect/runner/runner.py", line 571, in execute_flow_run
async with context:
^^^^^^^
File "/opt/pysetup/.venv/lib/python3.13/site-packages/prefect/runner/runner.py", line 1497, in __aenter__
await self._exit_stack.enter_async_context(
...<5 lines>...
)
File "/usr/local/lib/python3.13/contextlib.py", line 668, in enter_async_context
result = await _enter(cm)
^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.13/site-packages/prefect/runner/_observers.py", line 42, in __aenter__
self._events_subscriber = await self._exit_stack.enter_async_context(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...<5 lines>...
)
^
File "/usr/local/lib/python3.13/contextlib.py", line 668, in enter_async_context
result = await _enter(cm)
^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.13/site-packages/prefect/events/clients.py", line 555, in __aenter__
await self._reconnect()
File "/opt/pysetup/.venv/lib/python3.13/site-packages/prefect/events/clients.py", line 566, in _reconnect
self._websocket = await self._connect.__aenter__()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.13/site-packages/websockets/asyncio/client.py", line 587, in __aenter__
return await self
^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.13/site-packages/prefect/_internal/websockets.py", line 100, in _proxy_connect
proto = await self.__await_impl__()
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.13/site-packages/websockets/asyncio/client.py", line 543, in __await_impl__
await self.connection.handshake(
...<2 lines>...
)
File "/opt/pysetup/.venv/lib/python3.13/site-packages/websockets/asyncio/client.py", line 114, in handshake
raise self.protocol.handshake_exc
File "/opt/pysetup/.venv/lib/python3.13/site-packages/websockets/client.py", line 325, in parse
self.process_response(response)
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/opt/pysetup/.venv/lib/python3.13/site-packages/websockets/client.py", line 142, in process_response
raise InvalidStatus(response)
websockets.exceptions.InvalidStatus: server rejected WebSocket connection: HTTP 404
An exception occurred.
Marvin
08/06/2025, 2:40 PMMarvin
08/06/2025, 2:42 PMbash
# 1. Verify your PREFECT_API_URL in the worker environment
echo $PREFECT_API_URL
# 2. Test basic connectivity to your Prefect server
curl $PREFECT_API_URL/api/health
# 3. Check if your worker is properly configured
prefect worker status
4. Common Solutions:
- If you're using a reverse proxy (like nginx), ensure it's configured to handle WebSocket connections
- Check if your server URL uses the correct protocol (http/https)
- Verify that your Docker network configuration allows the worker to reach the Prefect server
Can you provide the following information to help diagnose the issue further?
1. How is your PREFECT_API_URL configured?
2. Are you using any reverse proxy in front of your Prefect server?
3. Can you share the relevant parts of your deployment configuration?
This error typically indicates that the worker can reach the server's HTTP endpoint but can't establish a WebSocket connection, which is crucial for real-time communication between the worker and the server. The 404 error specifically suggests that the WebSocket endpoint isn't being found at the expected location, which could be due to incorrect URL configuration or routing issues.Vincent Chéry
08/06/2025, 2:50 PMMarvin
08/06/2025, 2:50 PMMarvin
08/06/2025, 2:53 PMbash
# Basic server configuration
export PREFECT_SERVER_API_HOST="0.0.0.0" # Ensure server listens on all interfaces
export PREFECT_SERVER_API_PORT="4200" # Default port
export PREFECT_API_URL="<http://your-server-address:4200/api>" # Must be reachable from workers
# WebSocket specific settings
export PREFECT_SERVER_API_KEEPALIVE_TIMEOUT=300 # Adjust if needed (in seconds)
2. If Using a Reverse Proxy (e.g., Nginx)
Your reverse proxy must be configured to handle WebSocket connections. Here's an example Nginx configuration:
nginx
server {
listen 80;
server_name your-server-name;
location /api {
proxy_pass <http://localhost:4200;>
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket timeout settings
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
3. Verify Configuration
bash
# Test basic HTTP connectivity
curl <http://your-server-address:4200/api/health>
# Check server logs for WebSocket-related errors
prefect server start --log-level=DEBUG
4. Worker Configuration
Ensure your worker's configuration matches the server:
bash
# In your worker's environment
export PREFECT_API_URL="<http://your-server-address:4200/api>"
5. Common Issues to Check:
- Firewall rules: Ensure ports are open for both HTTP and WebSocket traffic
- DNS resolution: Make sure your server's hostname resolves correctly from worker containers
- Network routing: Check that there are no network policies blocking WebSocket connections
- SSL/TLS: If using HTTPS, ensure certificates are properly configured for WebSocket over SSL
To troubleshoot:
1. Start the server in debug mode:
bash
prefect server start --log-level=DEBUG
2. Watch the logs for WebSocket connection attempts when a flow runs.
3. Verify connectivity from the worker container:
bash
# From inside the worker container
curl -v $PREFECT_API_URL/health
If you're still experiencing issues, could you share:
1. Are you using any reverse proxy?
2. What's the exact value of your PREFECT_API_URL?
3. Can you run the server in debug mode and share any relevant log entries when the WebSocket connection fails?Vincent Chéry
08/06/2025, 3:19 PMMarvin
08/06/2025, 3:19 PMMarvin
08/06/2025, 3:20 PMbash
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
sudo a2enmod rewrite
2. Apache Virtual Host Configuration:
apache
<VirtualHost *:80>
ServerName your-server-name
# Enable rewrite engine
RewriteEngine On
# WebSocket upgrade rules
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/api/(.*) <ws://localhost:4200/api/$1> [P,L]
# Regular HTTP proxy
ProxyPass /api <http://localhost:4200/api>
ProxyPassReverse /api <http://localhost:4200/api>
# WebSocket specific settings
ProxyTimeout 300
# Additional recommended headers
RequestHeader set X-Forwarded-Proto "http"
RequestHeader set X-Forwarded-Port "80"
# If you need to set CORS headers
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Authorization, Content-Type"
</VirtualHost>
3. For HTTPS (recommended for production):
apache
<VirtualHost *:443>
ServerName your-server-name
SSLEngine on
SSLCertificateFile /path/to/your/certificate.crt
SSLCertificateKeyFile /path/to/your/private.key
# Enable rewrite engine
RewriteEngine On
# WebSocket upgrade rules for secure WebSocket (wss://)
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/api/(.*) <ws://localhost:4200/api/$1> [P,L]
# Regular HTTPS proxy
ProxyPass /api <http://localhost:4200/api>
ProxyPassReverse /api <http://localhost:4200/api>
# WebSocket specific settings
ProxyTimeout 300
# Additional recommended headers
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
# If you need to set CORS headers
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Authorization, Content-Type"
</VirtualHost>
4. After making changes, restart Apache:
bash
sudo systemctl restart apache2
Important Configuration Notes:
1. Replace your-server-name
with your actual server domain name
2. Adjust localhost:4200
to match your Prefect server's actual host and port
3. The ProxyTimeout
directive (300 seconds) should match your Prefect server's keep-alive timeout
4. For production environments:
- Always use HTTPS (the second configuration)
- Adjust CORS headers to be more restrictive than "*"
- Consider adding authentication headers if needed
Troubleshooting:
1. Check Apache error logs:
bash
tail -f /var/log/apache2/error.log
2. Verify modules are loaded:
bash
apache2ctl -M | grep proxy
3. Test the configuration:
bash
apache2ctl -t
If you encounter any issues, you can:
1. Enable more verbose logging by adding:
apache
LogLevel debug proxy:trace5
2. Check connectivity:
bash
# Test HTTP
curl -v <http://your-server-name/api/health>
# For HTTPS
curl -v -k <https://your-server-name/api/health>
Would you like me to explain any part of this configuration in more detail?