Saad80
09/24/2025, 3:07 AMMarvin
09/24/2025, 3:07 AMMarvin
09/24/2025, 3:11 AM/flow_runs/{id}/labels, but the server you’re talking to doesn’t expose that endpoint, so you get a 404. This almost always points to a version mismatch where the worker/client is newer than the server.
What to check/try:
- Are you on Prefect Cloud or self-hosting Prefect Server?
- Please run prefect version on:
  - the machine/container running your worker
  - the machine/container running your server (if self-hosted)
  and share both outputs.
Immediate remediation options:
- Upgrade your Prefect Server to the latest 3.x (and keep your workers on the same version).
- If you can’t upgrade the server right now, temporarily pin your worker to a 3.0.x version (before workers attempted to write labels to flow runs).
Quick self-checks:
- Open your API docs at <YOUR_PREFECT_API_URL>/docs and search for “labels” or “update_flow_run_labels”. If it’s missing, your server version does not support that route yet.
- This route is documented here: Update flow run labels (Prefect 3.x API)
- There isn’t a setting to disable label updates from workers (no PREFECT_API_ENABLE_LABELS or similar), so compatibility is the fix.
Related report for context:
- This GitHub issue describes the same 404 on /flow_runs/{id}/labels when versions diverged: Process workpool doesn’t make a flow run
If you can share:
- Prefect versions (server and worker)
- Whether you’re in Cloud or OSS
- The server image tag (if self-hosted)
…I can give you a precise upgrade/pin recommendation.Saad80
09/24/2025, 3:15 AMMarvin
09/24/2025, 3:15 AMMarvin
09/24/2025, 3:16 AM/flow_runs/{id}/labels. That endpoint does not exist on a Prefect 2.x server, so the server returns 404. In other words: your worker (or whatever is submitting the run) is running Prefect 3.x, but your self‑hosted server is Prefect 2.14.20.
Key point: Prefect 2 and Prefect 3 are not API-compatible. A 3.x client will try to hit endpoints (like flow run labels) that a 2.x server does not have, causing exactly this 404.
How to confirm quickly
- On the worker machine/container: run
prefect version
- On your server container/host: run
prefect version
You’ll likely see 3.x on the worker and 2.14.20 on the server.
Ways to fix (pick one)
- Keep everything on Prefect 2.14.20
  - Pin the worker environment to 2.14.20:
    - pip: 
    pip install "prefect==2.14.20"
    - Docker image/tag (example):
    prefecthq/prefect:2.14.20-python3.11
  - Make sure any CI/CD or container rebuilds aren’t pulling latest (which is 3.x now).
- Or upgrade fully to Prefect 3.x
  - Upgrade your self-hosted server and all workers to the same 3.x version.
  - Note: in 3.x, workers do add their labels to flow runs; the route is documented here:
    Update flow run labels (Prefect 3.x API)
Related report for context (same 404 on /labels when versions diverged):
- Process work pool 404 on /flow_runs/{id}/labels
If you share:
- the prefect version output from your worker and server
- how you’re running the worker (pip/venv vs Docker/Kubernetes) and the exact image/tag or package pin
…I can give you exact pin/upgrade commands for your setup.Saad80
09/24/2025, 3:28 AMMarvin
09/24/2025, 3:28 AMMarvin
09/24/2025, 3:29 AM/usr/local/lib/python3.11/site-packages/...)
- It’s calling the 3.x-only endpoint /flow_runs/{id}/labels via update_flow_run_labels
Prefect 2.x servers don’t have that labels route, so a 3.x worker/client will get a 404 exactly like you’re seeing.
What likely happened
- The worker that actually picked up the flow is running somewhere else (container/VM) with Prefect 3.x (often due to using an image/tag like prefecthq/prefect:latest).
- Your server remains on 2.14.20, causing a mismatch.
Confirm the worker version (on the machine/container that runs the worker)
- Process worker on a host:
  which prefect
  prefect version
  python -c "import prefect, sys; print(prefect.__version__, sys.version)"
- Docker worker:
  docker ps | grep prefect
  docker exec -it <container_id> prefect version
- Kubernetes worker:
  kubectl get pods -n <ns>
  kubectl exec -it <pod> -n <ns> -- prefect version
You should see 3.x on the worker that threw this error.
Fix options (pick one and keep everything aligned):
- Stay on Prefect 2.14.20 everywhere
  - Pin the worker to 2.14.20 and restart it:
    pip install "prefect==2.14.20"
    or, for Docker/K8s, use an explicit image tag like:
    prefecthq/prefect:2.14.20-python3.11
    Make sure your templates/manifests aren’t using :latest.
- Or upgrade fully to Prefect 3.x (server and all workers)
  - If you go this route, that labels endpoint exists and the error goes away. Route reference: Update flow run labels (Prefect 3.x API)
Related report (same 404 when versions diverged):
- Process work pool 404 on /flow_runs/{id}/labels
If you share:
- how your worker is deployed (Process, Docker, Kubernetes)
- the exact image/tag or Python env it uses
- the output of prefect version from inside that worker
…I can give you the exact pin/upgrade steps for your setup.Saad80
09/24/2025, 4:37 PM16:36:27.305 | WARNING | prefect.events.clients - Unable to connect to 'ws://****.<http://ap-south-1.compute.amazonaws.com:4200/api/events/in|ap-south-1.compute.amazonaws.com:4200/api/events/in>'. Please check your network settings to ensure websocket connections to the API are allowed. Otherwise event data (including task run data) may be lost. Reason: server rejected WebSocket connection: HTTP 403. Set PREFECT_DEBUG_MODE=1 to see the full error.Marvin
09/24/2025, 4:37 PMMarvin
09/24/2025, 4:39 PMprefect.events.clients and targets /api/events/in over a WebSocket. That events ingress WebSocket is a Prefect 3.x feature. A 2.x server does not expose this route. A 3.x client will try to open it and, depending on your proxy, you’ll get a 403/404 instead of a clean upgrade.
First, please confirm the version in the environment producing this warning (the worker/container/pod that’s running your flow):
- If it’s a host process:
which prefect
prefect version
python -c "import prefect, sys; print(prefect.__version__, sys.version)"
- If it’s Docker:
docker ps | grep prefect
docker exec -it <container_id> prefect version
- If it’s Kubernetes:
kubectl get pods -n <ns>
kubectl exec -it <pod> -n <ns> -- prefect version
If that shows 3.x, the fix is to align versions:
- Stay on Prefect 2.14.20 everywhere
  - Pin your worker image/env to 2.14.20 and restart it
  - Do not use :latest images; use explicit tags like prefecthq/prefect:2.14.20-python3.11 or pip install "prefect==2.14.20"
- Or upgrade your server and all workers to 3.x together
If you truly are 2.14.20 everywhere and still see a WebSocket 403:
- That would point to your reverse proxy/LB blocking WS upgrades. Ensure it forwards WebSocket upgrades to the Prefect API.
- Nginx example:
map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}
location /api/ {
  proxy_pass <http://prefect-server:4200;>
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection $connection_upgrade;
  proxy_set_header Host $host;
  proxy_read_timeout 600s;
}
- AWS ALB:
  - ALB supports WebSockets over HTTP/1.1; ensure listener/protocols are HTTP/HTTPS, idle timeout >= 300s, security groups/WAF allow Upgrade/Connection headers and the /api/events/in path to the target.
- Also make sure your PREFECT_API_URL scheme matches your deployment. If you terminate TLS at the proxy, clients should reach https://.../api (which implies wss:// for WebSockets), not ws:// over a TLS-only endpoint.
To get more detail, set:
export PREFECT_DEBUG_MODE=1
and reproduce; share the expanded error and I can help pinpoint whether it’s a proxy/WAF rejection or a version mismatch.
Given your earlier 404 on /flow_runs/{id}/labels, I’d prioritize verifying the worker’s Prefect version first — aligning versions will likely clear both errors. If you share how your worker is deployed (Process, Docker, K8s) and the exact image/tag or pip pin, I’ll provide exact pin/upgrade steps.Saad80
09/24/2025, 5:30 PMMarvin
09/24/2025, 5:30 PMMarvin
09/24/2025, 5:31 PMprefect version check. That’s why:
- the worker later behaves like a 3.x client (trying to call /flow_runs/{id}/labels and the events websocket), and
- your 2.x server returns 404/403.
Fix options
- Stay on Prefect 2.14.20 everywhere
  - Use a Prefect 2-compatible AWS integration: pin prefect-aws to <0.3.0 (the 0.2.x line)
  - Explicitly pin Prefect in the pip step to prevent upgrades
  - You don’t need to pin `pydantic`; Prefect 2 will bring Pydantic v1 automatically
Example ECS command (reorders to install first, then prints versions so you see the final resolved state):
/bin/sh -c "
  pip install --no-cache-dir --upgrade --upgrade-strategy only-if-needed \
    'prefect==2.14.20' 'prefect-aws<0.3.0' 'boto3<2' \
  && python -c 'import prefect, pydantic; print(\"prefect:\", prefect.__version__, \"pydantic:\", pydantic.__version__)' \
  && prefect version \
  && prefect worker start --pool ecs-two-flows --type ecs
"
Even better, bake a custom image with those packages preinstalled and drop the runtime pip installs to reduce startup time and avoid accidental upgrades.
- Or upgrade to Prefect 3.x end-to-end
  - Upgrade your self-hosted server and all workers to the same 3.x version
  - Then prefect-aws==0.3.x is correct, and the labels endpoint and events websocket will work
Why you saw the issues
- 404 on `/flow_runs/{id}/labels`: 3.x client feature hitting a 2.x server that doesn’t have that route
- 403 on /api/events/in websocket: 3.x client tries to open the events WS; your 2.x server/proxy rejects it
Reference (same symptom when versions diverge):
- https://github.com/PrefectHQ/prefect/issues/16828
If you’d like, share the worker logs after applying the change (the python -c ... printout + prefect version) and I’ll double-check the final versions.