Troubleshooting Installation
Common installation problems, their root causes, and step-by-step solutions with commands.
Published Jun 2, 2026
Introduction
Installing software on ARM64 edge devices involves more moving parts than a typical cloud server. You are dealing with Python versions, C compilers, hardware-specific CPU extensions, microSD card I/O, and network conditions that vary from site to site. This article is a diagnostic manual for the most common problems beginners encounter when installing Pyvorin Edge. Each problem includes the symptom, the root cause, and the exact commands to fix it.
Problem 1: Permission Denied During pip Install
Symptom
ERROR: Could not install packages due to an OSError: [Errno 13] Permission denied: '/usr/local/lib/python3.12/dist-packages/...'
Root Cause
You are trying to install packages into the system Python directories without root privileges. Even if you use sudo, installing into system Python with pip is discouraged because it can break OS-managed packages.
Solution
Always use a virtual environment. Do not use sudo pip.
# Step 1: Create a virtual environment
python3.12 -m venv ~/pyvorin-edge/.venv
# Step 2: Activate it
source ~/pyvorin-edge/.venv/bin/activate
# Step 3: Install inside the venv
pip install pyvorin-edge-runtime pyvorin-edge-sdk
If you already ran sudo pip and suspect system Python corruption, check for conflicting packages:
pip list --format=freeze | grep -i pyvorin
# If any appear outside the venv, remove them carefully:
sudo pip uninstall pyvorin-edge-runtime pyvorin-edge-sdk
Problem 2: Missing Python Headers
Symptom
fatal error: Python.h: No such file or directory
#include
^~~~~~~~~~
compilation terminated.
error: command 'gcc' failed with exit status 1
Root Cause
The python3.12-dev (or equivalent) package is not installed. This package provides the C header files required to compile Python extensions and native kernels.
Solution
Install the development headers that match your exact Python version:
# Find your Python version
python3 --version
# Example output: Python 3.12.3
# Install matching headers
sudo apt update
sudo apt install -y python3.12-dev
# If you built Python from source, the headers are already present
# in your prefix directory (e.g., /usr/local/include/python3.12).
After installing headers, retry the pip install or compilation step that failed.
Problem 3: NEON Extension Build Failures
Symptom
error: unknown directive
.arch armv8-a+fp+simd
^
Or, at runtime:
OSError: /home/pi/pyvorin-edge/kernels/temp_check.so: cannot open shared object file: No such file or directory
Root Cause
One of three things:
- You are on a 32-bit ARM system (armv7l) that does not support ARM64/NEON.
- Your GCC version is too old to recognise ARMv8 NEON intrinsics.
- The compiler bridge failed silently and did not produce the
.sofile.
Solution
Step 1: Verify architecture.
uname -m
# Must print: aarch64
If it prints armv7l, you are on 32-bit. You must reinstall a 64-bit operating system (Raspberry Pi OS 64-bit or Ubuntu 24.04 ARM64).
Step 2: Verify NEON support in CPU flags.
grep -i "neon\|asimd" /proc/cpuinfo | head -1
# Should contain 'asimd' (ARM64 NEON)
Step 3: Update GCC.
sudo apt update
sudo apt install -y gcc g++ build-essential
gcc --version
# Should be 10.x or newer on Raspberry Pi OS / Debian 12
Step 4: Test a manual compilation.
cat > /tmp/test_neon.c << 'EOF'
#include
int main() {
float32x4_t a = vdupq_n_f32(1.0f);
return 0;
}
EOF
gcc -o /tmp/test_neon /tmp/test_neon.c
# If this succeeds, your toolchain supports NEON.
Step 5: Debug the compiler bridge.
import logging
logging.basicConfig(level=logging.DEBUG)
from pyvorin_edge.compiler_bridge import CompilerBridge
bridge = CompilerBridge()
try:
path = bridge.compile_hotpath(
source_code="def f(x): return x + 1",
function_name="f",
output_path="/home/pi/pyvorin-edge/kernels/test.so"
)
print("Compiled to:", path)
except Exception as exc:
print("Compilation failed:", exc)
If the scalar compiler is unavailable, ensure the full pyvorin compiler package is installed.
Problem 4: Port Conflicts
Symptom
OSError: [Errno 98] Address already in use
Or the dashboard shows "Agent unreachable" even though the agent appears to be running.
Root Cause
Another process is already bound to TCP port 8080 (or whatever port you configured for the health server). Common culprits include:
- A previously crashed agent process that did not release its socket.
- Another instance of the agent started by systemd.
- Apache, nginx, or another web server listening on 8080.
- Docker containers with port mappings.
Solution
Step 1: Identify the occupant.
sudo ss -tlnp | grep 8080
# or
sudo lsof -i :8080
Step 2: If it is a zombie agent, kill it.
ps aux | grep pyv-edge
kill -9
Step 3: Change the agent port.
# config.toml
[health]
port = 8081
enabled = true
Remember to update the dashboard settings to point at the new port.
Problem 5: CORS Issues in the Browser
Symptom
The dashboard loads but shows blank charts. The browser console displays:
Access to fetch at 'http://192.168.1.45:8080/health' from origin 'http://localhost:8000'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present.
Root Cause
The agent's health server is not sending CORS headers, or a browser extension / corporate proxy is stripping them. By default, Pyvorin Edge does send Access-Control-Allow-Origin: *, so this usually means something else is intercepting the response.
Solution
Step 1: Verify headers with curl.
curl -v http://192.168.1.45:8080/health 2>&1 | grep -i access-control
# Expected: < Access-Control-Allow-Origin: *
Step 2: If headers are missing, check for a proxy.
# Are you behind a corporate proxy?
echo $http_proxy
echo $https_proxy
# Temporarily bypass for testing
curl -v --noproxy "*" http://192.168.1.45:8080/health
Step 3: Run dashboard and agent on the same origin.
If CORS cannot be resolved, serve the dashboard static files from the same host and port as the agent using a reverse proxy (see the Dashboard Overview article for an nginx example).
Problem 6: Mixed Content HTTPS/HTTP
Symptom
When the dashboard is served over HTTPS (e.g., at https://app.pyvorin.com), the browser blocks HTTP requests to the agent:
Mixed Content: The page at 'https://app.pyvorin.com' was loaded over HTTPS,
but requested an insecure resource 'http://192.168.1.45:8080/health'.
This request has been blocked; the content must be served over HTTPS.
Root Cause
Modern browsers forbid HTTPS pages from making active HTTP requests to protect against man-in-the-middle attacks.
Solution
You have three options:
- Serve the dashboard over HTTP. Only suitable for local network access.
- Use a local HTTPS tunnel. Tools like
ngrokorcloudflaredcan expose your agent's HTTP endpoint as an HTTPS URL. - Set up a reverse proxy with TLS termination. Place nginx or Traefik in front of the agent, terminating TLS with a certificate from Let's Encrypt or your internal CA.
Example: Local Tunnel with cloudflared
# Install cloudflared
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64
chmod +x cloudflared-linux-arm64
sudo mv cloudflared-linux-arm64 /usr/local/bin/cloudflared
# Create a quick tunnel
cloudflared tunnel --url http://localhost:8080
# This prints an HTTPS URL like https://something.trycloudflare.com
# Use that URL in your remote dashboard settings.
Problem 7: Agent Starts but No Readings Appear
Symptom
{"ts": ..., "level": "INFO", "logger": "pyv_edge_agent.main", "msg": "EdgeAgent started"}
# ... then silence. No readings processed.
Root Cause
Usually one of:
- No devices configured in
[sensors.devices]. - A device is configured but has no
namekey, so the adapter initialisation is skipped. - The adapter import failed (e.g., MQTT adapter without
paho-mqttinstalled). - The poll interval is set to an unexpectedly large value.
Solution
# Verify config syntax
cd ~/pyvorin-edge
python3 -c "from pyv_edge_agent.config import Config; c = Config.from_file('config.toml'); print(c.validate())"
# Should print an empty list [] if valid.
# Check for adapter warnings in logs
pyv-edge --config config.toml 2>&1 | grep -i warning
# Verify at least one device is configured
curl -s http://localhost:8080/health | python3 -c "import sys,json; print(json.load(sys.stdin)['ingest']['devices_configured'])"
Problem 8: SQLite Database Locked
Symptom
sqlite3.OperationalError: database is locked
Root Cause
SQLite with WAL mode is highly concurrent, but if you are manually querying the database with a tool that opens a transaction and keeps it open (e.g., the sqlite3 CLI with an uncommitted transaction), it can block the agent's writers.
Solution
Use read-only queries and keep transactions short:
# Safe: quick select
sqlite3 /home/pi/pyvorin-edge/data/edge_store.db "SELECT * FROM readings LIMIT 5;"
# Risky: opening interactive session while agent is writing
# sqlite3 /home/pi/pyvorin-edge/data/edge_store.db
# > BEGIN;
# > SELECT * FROM readings;
# -- leave this open and the agent may see "database is locked"
Summary
Most installation problems fall into a few categories: permissions (use a venv), missing system dependencies (install -dev packages), architecture mismatches (use 64-bit ARM), port conflicts (change the port or kill the occupant), and network issues (CORS, HTTPS, proxies). Work through the symptom → cause → solution pattern above, and remember that the agent's JSON logs and the /health endpoint are your best diagnostic tools.