How to Fix Dify Tavily Plugin Installation Failure: “signal: killed” and “failed to init environment”
If you’ve tried installing the Tavily search plugin in Dify and hit an error like this, you’re not alone:
failed to launch plugin: failed to install dependencies: signal: killed
... Downloading tiktoken (1.1MiB)
Downloading pydantic-core (2.0MiB)
Downloading gevent (2.0MiB)
Downloaded tiktoken
failed to init environment
This guide walks through the exact diagnosis steps, explains the root cause, and provides two fixes — one immediate, one permanent.
Environment
-
Server: Alibaba Cloud ECS -
RAM: 14 GB -
Dify version: 1.14.2 (Docker Compose deployment) -
Plugin Daemon image: langgenius/dify-plugin-daemon:0.6.1-local
Step-by-Step Diagnosis
Step 1 — Find the Correct Container Name
The first instinct is to check logs, but the container name isn’t what you might expect:
sudo docker logs dify-plugin-daemon
# Error response from daemon: No such container: dify-plugin-daemon
List all Dify-related containers to find the real name:
sudo docker ps -a | grep dify
The plugin daemon container is named docker-plugin_daemon-1.
Step 2 — Run the Diagnostic Trio
Before drawing any conclusions, collect three data points:
# Check available memory
free -h
# Check whether the uv process is still running inside the container
sudo docker exec docker-plugin_daemon-1 ps aux | grep uv
# Check for OOM kill events in kernel logs
dmesg | grep -E "oom|killed|Out of memory" | tail -20
The results were surprising:
total used free available
Mem: 14Gi 1.8Gi 3.3Gi 12Gi ← Plenty of memory
root 72 0.2 0.5 895580 89856 Sl 11:37 /usr/local/bin/uv sync ...
← uv is still running
(no output from dmesg) ← No OOM kill
Memory was not the issue. The uv process was alive. No OOM events. So the problem lay elsewhere.
Step 3 — Wait for the Full Error
With the process still running, tail the logs and wait:
sudo docker logs docker-plugin_daemon-1 --tail 100
A few minutes later, the real error surfaced:
11:42:41 ERROR local runtime start failed
plugin=langgenius/tavily:0.1.10
error="failed to install dependencies: signal: killed, output:
...
DEBUG No cache entry for: https://files.pythonhosted.org/packages/.../gevent-26.5.0...
DEBUG Sending fresh GET request for: https://files.pythonhosted.org/packages/.../gevent-26.5.0...
...
Downloading tiktoken (1.1MiB)
Downloading pydantic-core (2.0MiB)
Downloading gevent (2.0MiB)
Downloaded tiktoken
failed to init environment"
Root Cause: uv --frozen Ignores Your Mirror for Actual Downloads
The daemon logs showed this uv invocation:
uv sync --no-dev --frozen -i https://pypi.tuna.tsinghua.edu.cn/simple -v
A Chinese PyPI mirror was already configured via -i. That looks fine — but the debug output told a different story:
DEBUG Sending fresh GET request for: https://files.pythonhosted.org/packages/.../gevent...
DEBUG Sending fresh GET request for: https://files.pythonhosted.org/packages/.../pydantic_core...
The actual wheel files were still being fetched directly from files.pythonhosted.org.
Here’s why:
-
The -iflag (or--index-url) only controls where uv looks up package metadata — think of it as changing which catalog you browse. -
When --frozenis used, uv strictly follows the URLs locked inuv.lock. Those URLs hardcodefiles.pythonhosted.orgas the download source. -
As a result, metadata comes from the mirror, but the actual .whlfiles are still pulled from PyPI’s origin servers.
On a server with slow or throttled access to files.pythonhosted.org, downloading gevent (2 MB) + pydantic-core (2 MB) + tiktoken (1.1 MB) and other dependencies exceeds the plugin daemon’s internal timeout. The process gets killed with SIGKILL, producing the signal: killed error.
The Fix
Option 1 — Pre-Warm the uv Cache (Immediate Fix)
uv maintains a global wheel cache (default: ~/.cache/uv). If the required packages are already cached, uv sync --frozen completes instantly without downloading anything.
The trick is to run uv sync manually inside the container — bypassing the daemon’s timeout — and let it download at its own pace.
# Enter the container
sudo docker exec -it docker-plugin_daemon-1 bash
# Find the extracted plugin directory
ls /app/storage/cwd/langgenius/ | grep tavily
# Navigate to the plugin directory (use the full name from the output above)
cd /app/storage/cwd/langgenius/tavily-0.1.10@b43f5dc49fbafc69...
# Run uv sync manually with a generous HTTP timeout
UV_HTTP_TIMEOUT=600 /usr/local/bin/uv sync --no-dev --frozen -v
# Exit once complete
exit
After the manual sync finishes, go back to the Dify UI and reinstall the Tavily plugin. This time uv finds everything in cache and completes in seconds.
Option 2 — Increase the uv Timeout (Permanent Fix)
Edit your docker-compose.yaml and add the following environment variables to the plugin_daemon service:
plugin_daemon:
environment:
- UV_HTTP_TIMEOUT=600
- UV_REQUEST_TIMEOUT=600
Restart the service to apply:
sudo docker compose up -d plugin_daemon
This prevents timeout failures when installing any plugin in the future, not just Tavily.
Summary
| Symptom | Initial Assumption | Actual Cause |
|---|---|---|
signal: killed |
OOM / insufficient memory | Download timeout — daemon kills uv after too long |
| PyPI mirror already configured | Network issue resolved | -i only affects metadata; --frozen fetches actual files from hardcoded files.pythonhosted.org URLs |
| 12 GB free memory | Hardware is not the bottleneck | Correct — but irrelevant; the bottleneck is network I/O timeout |
TL;DR: When uv runs with --frozen, it ignores the -i mirror flag for actual package downloads and uses the original files.pythonhosted.org URLs locked in uv.lock. On servers with slow access to PyPI’s origin, this causes the installation to time out and fail. Pre-warming the uv cache or increasing UV_HTTP_TIMEOUT resolves the issue.
Frequently Asked Questions
Does this affect all Dify plugins, or just Tavily?
Any plugin that requires large binary wheels (compiled C extensions) is at risk. Packages like gevent, pydantic-core, tiktoken, and numpy are common culprits. If you see signal: killed during dependency installation, this is likely the cause.
Will the uv cache persist across container restarts?
By default, the uv cache lives inside the container and will be lost if the container is recreated. To make the cache persistent, mount a volume for /root/.cache/uv in docker-compose.yaml. That said, the UV_HTTP_TIMEOUT fix in Option 2 is the more robust long-term solution.
Why does tiktoken download successfully but pydantic-core and gevent fail?
uv downloads multiple packages in parallel. tiktoken (1.1 MB) happens to finish before the timeout. gevent (2 MB) and pydantic-core (2 MB) are larger and take longer, so they’re still in flight when the kill signal arrives.
Tested on: Dify 1.14.2 · dify-plugin-daemon 0.6.1-local · uv 0.11.14 · Alibaba Cloud ECS

