#17470·OpenHands

Agent server crashes with SIGILL on Apple Silicon under Colima (OpenSSL ARM capability misdetection)

Author: wmxicqyCreated Sep 16, 2026Updated Sep 17, 2026
Labelsbugdockeragent-canvaspriority:medium

Summary

On Apple Silicon with Colima (Virtualization.framework, native aarch64 — no emulation), both openhands-agent-server and the automation server die immediately with Illegal instruction (SIGILL). The frontend starts fine, so the only user-visible symptom is the onboarding screen stuck on "Disconnected" with no actionable error.

Root cause is OpenSSL's ARM capability detection inside the cryptography wheel's statically-linked OpenSSL, not anything OpenHands-specific — but the image ships the affected combination and the failure is silent.

Minimal reproduction

docker run --rm --entrypoint python ghcr.io/openhands/agent-canvas:1.18.0 -c "import litellm"
# exit code 132 (128 + SIGILL)

With the OpenSSL capability override, it succeeds:

docker run --rm -e OPENSSL_armcap=0 --entrypoint python \
  ghcr.io/openhands/agent-canvas:1.18.0 -c "import litellm"
# OK

Actual container logs

[agent-canvas] Starting agent-server on port 18000...
[agent-canvas] Starting automation server on port 18001...
[agent-canvas] WARNING: Agent Server on port 18000 did not become ready within 60s
[agent-canvas] WARNING: Automation Server on port 18001 did not become ready within 60s
/opt/agent-canvas/entrypoint.sh: line 371: 24 Illegal instruction  openhands-agent-server --port "$AGENT_SERVER_PORT" ...
/opt/agent-canvas/entrypoint.sh: line 371: 29 Illegal instruction  uvicorn openhands.automation.app:app ...
[agent-canvas] Starting frontend + proxy on port 8000...
[agent-canvas] All services started. Unified entry point: http://0.0.0.0:8000/
[static:8000] Proxy error -> http://127.0.0.1:18000/: connect ECONNREFUSED 127.0.0.1:18000
  (repeats indefinitely)

Root cause

Crash localises to the Rust extension of cryptography, which statically links OpenSSL:

import litellm
  └─ cryptography.hazmat.bindings._rust   ← SIGILL here

python -v import trace stops right after cryptography.hazmat.bindings, immediately before loading _rust.so.

The guest kernel advertises a very wide HWCAP feature set:

fp asimd ... sha3 sha512 ... sve2 ... sme sme2 sme2p1 ...

OpenSSL picks an accelerated assembly path based on those capability bits, and the instruction it then executes traps under Virtualization.framework. Setting OPENSSL_armcap=0 forces the generic C implementations and everything works.

Verified end-to-end — with OPENSSL_armcap=0 the agent server is ready in ~4s:

uvicorn.error  Application startup complete.
uvicorn.access GET /health HTTP/1.1  200

Environment

Host Apple M5, macOS 26.6.2
Container runtime Colima 0.8.1 (Virtualization.framework, mountType: sshfs), Docker 28.1.1
Arch aarch64 host / aarch64 guest / aarch64 image — no emulation involved
Image ghcr.io/openhands/agent-canvas:1.18.0
Python 3.13.15
cryptography 50.0.1
OpenSSL (bundled) 4.0.2 (25 Aug 2026)

Workaround

docker run -it --rm -p 8000:8000 \
  -e OPENSSL_armcap=0 \
  -v "$HOME/.openhands:/home/openhands/.openhands" \
  -v "${PROJECTS_PATH}:/projects" \
  ghcr.io/openhands/agent-canvas:1.18.0

Suggestions

  1. Fail loudly. entrypoint.sh logs a WARNING on the readiness timeout but then reports "All services started" and keeps the proxy running. The child processes had already died. Surfacing the child exit status (132 → SIGILL) would turn a confusing "Disconnected" screen into a one-line diagnosis.
  2. Consider defaulting OPENSSL_armcap=0 on aarch64 Linux, or pinning a cryptography build that links the system OpenSSL. The performance cost is negligible for an IO-bound workload.
  3. Colima on Apple Silicon is a common Docker Desktop alternative, so this likely affects more than one user. Worth a note in the docs even if the code fix lands upstream.