Skip to content

Error codes (EDG)

Every install, preflight, edgible doctor, and self-update failure line carries a stable EDG### code. Search this page for the code in your output — each entry says what happened, why, and the exact command to fix it.

RangeArea
1xxEnvironment and dependencies on the local host
2xxNetwork, platform reachability, and credentials
3xxAgent first-connect stages (after the service starts)
4xxArtifact distribution and install operations
5xxCLI self-update
6xxUninstall

Deploy and device failures are reported differently: the API returns a named code string in its error body, and the agent stamps one on a failed deployment. Those have no EDG number — the ones you’re most likely to meet are listed under Code-artifact deploy errors and Deploy and job errors at the end of this page.

EDG100 — Unsupported operating system or architecture

Section titled “EDG100 — Unsupported operating system or architecture”

What happened: The installer refused to run on this platform.

Why: Edgible supports Linux and macOS on x86_64 and arm64. Windows is not yet supported.

Fix: Re-run the install on a supported host. Check yours with uname -sm.

What happened: The install could not create or write to its target directory.

Why: The chosen prefix (e.g. /opt/edgible-cli or the agent config dir) needs privileges this user doesn’t have.

Fix (a system install): Re-run with sudo, or point the install at a user-writable path (EDGIBLE_CLI_PREFIX=$HOME/.edgible/cli for the CLI installer).

Fix (an install under your own account): This is your own data directory, so sudo is the wrong answer — it would move the install to the wrong paths. The usual cause is a folder an earlier sudo edgible command created as root. Take it back, then re-run:

Terminal window
sudo chown -R "$(id -un)" ~/.local/share/edgible # Linux
sudo chown -R "$(id -un)" ~/Library/Application\ Support/Edgible # macOS

Related: EDG502

What happened: The service manager the install method needs (systemctl, launchctl, …) is not available.

Why: This host doesn’t run the init system the chosen install type manages the agent with — commonly a minimal container image without systemd.

Fix: Install on a host running the expected init system, or use --type foreground to run the agent without a daemon manager.

Related: EDG122

What happened: Node.js is missing, older than 20, or sits at an unstable path (e.g. an npx temp dir the daemon unit would hard-code).

Why: The CLI, SDK, and agent all require Node.js 20+ at a stable path.

Fix: Install Node 20+ and re-run — brew install node (macOS), curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash - && sudo apt-get install -y nodejs (Debian/Ubuntu), or nvm install 20. The CLI installer can do this for you (EDGIBLE_INSTALL_NODE=1).

What happened: The target filesystem has less free space than the install needs (~500MB for the CLI bundle, ~300MB–1GB for the agent).

Why: The unpacked bundle includes its vendored node_modules.

Fix: Free up space on the target filesystem (df -h <target> shows usage) and re-run.

What happened: The installer needs curl to download artifacts and it’s not on PATH.

Fix: sudo apt-get install -y curl (or your distro’s equivalent), then re-run.

Related: EDG106

What happened: The installer needs unzip to extract the bundle and it’s not on PATH.

Fix: sudo apt-get install -y unzip (or your distro’s equivalent), then re-run.

Related: EDG105

What happened: The wg binary is missing.

Why: The agent manages device-pool tunnels with the WireGuard userspace tools.

Fix: sudo apt-get install -y wireguard (Debian/Ubuntu), dnf install -y wireguard-tools (Fedora), or brew install wireguard-tools (macOS). edgible agent install can install it for you when you accept the prompt.

Related: EDG114, EDG120

EDG111 — Caddy not installed (serving device)

Section titled “EDG111 — Caddy not installed (serving device)”

What happened: The caddy binary is missing on a serving device.

Why: Serving devices terminate TLS for workloads with Caddy.

Fix (a system install): sudo apt-get install -y caddy (or brew install caddy). On Alpine, enable the community repository in /etc/apk/repositories first.

Fix (an install under your own account): don’t install a package — an install without sudo downloads its own Caddy alongside the agent and runs that copy. Re-run the install so it is fetched again:

Terminal window
edgible agent install

Related: EDG117

EDG112 — HAProxy not installed (gateway device)

Section titled “EDG112 — HAProxy not installed (gateway device)”

What happened: The haproxy binary is missing on a gateway device.

Why: Gateways route inbound traffic to serving devices through HAProxy.

Fix: sudo apt-get install -y haproxy (or your distro’s equivalent), then re-run the install.

What happened: The iptables binary is missing.

Why: The agent programs NAT/forwarding rules for the WireGuard data path.

Fix: sudo apt-get install -y iptables (or your distro’s equivalent), then re-run.

What happened: The userspace WireGuard implementation is missing on a host that needs it.

Why: When the kernel module can’t be used (macOS, some containers/kernels), the agent falls back to wireguard-go.

Fix: brew install wireguard-go (macOS) or install wireguard-go from your package manager, then re-run.

Related: EDG110, EDG120

EDG115 — Configured wireguard-go binary not found

Section titled “EDG115 — Configured wireguard-go binary not found”

What happened: The wireguard-go binary the agent is configured to use does not exist. The failure names the exact path (or bare name) that was probed: either the wireguardGoBinary override from the config being installed / the device’s existing agent.config.json, or — when no override is set — wireguard-go on PATH.

Why: On hosts that run userspace WireGuard (macOS, Windows, Linux with wireguardMode: userspace), the agent cannot bring up tunnels without this binary. The install verifies it up front; previously a bad path only surfaced an hour later as EDG306 handshake failures blaming the network.

Fix: Install wireguard-go (brew install wireguard-go on macOS, or your distro’s package), or fix the override with edgible config set wireguardGoBinary <path> — or unset it so the agent resolves wireguard-go on PATH — then re-run.

Related: EDG114, EDG120, EDG306

EDG116 — Built-in tunnel helper missing or will not run

Section titled “EDG116 — Built-in tunnel helper missing or will not run”

What happened: The agent’s built-in tunnel helper — the small binary that carries the device’s encrypted tunnel — is not where the agent expects it, or it is there but will not execute.

Why: The helper ships inside the agent release and is placed alongside the agent when it is installed. It goes missing when an install was interrupted partway, when a release directory was edited by hand, or when a netstackHelperBinary override in agent.config.json points at a path that no longer exists.

Fix: Re-run the install so the helper is fetched again — the way this agent was installed:

Terminal window
sudo edgible agent install # if the agent runs as a system service
edgible agent install # if it runs under your own account

If you set a helper path by hand in agent.config.json, either correct it or remove the key and let the agent use the copy that ships with its release.

Related: EDG117, EDG306

EDG117 — Caddy missing or too old for this device

Section titled “EDG117 — Caddy missing or too old for this device”

What happened: A serving device using the built-in tunnel needs Caddy 2.10.2 or newer, and this host has an older Caddy — or none at all.

Why: With the built-in tunnel the device hands traffic to Caddy over a local socket, and older Caddy builds cannot read the client’s real address on that kind of listener. The failure mode is the reason this is caught before the install rather than after: an unsupporting Caddy starts up perfectly happily and then breaks every request to every application on the device with a TLS error that names nothing.

Fix (a system install):

Terminal window
sudo apt-get install -y caddy # Debian/Ubuntu (or: sudo dnf install -y caddy)
brew upgrade caddy # macOS

Confirm with caddy version, then re-run the install.

Fix (an install under your own account): the agent runs the Caddy that was downloaded with it, so a package manager is the wrong tool. Re-run the install so the web server is fetched again:

Terminal window
edgible agent install

Related: EDG111

EDG120 — WireGuard kernel module not loadable

Section titled “EDG120 — WireGuard kernel module not loadable”

What happened: /sys/module/wireguard is absent and modprobe -n wireguard failed. If wireguard-go is present this is a warning — kernel mode will still be attempted and may fail at tunnel creation unless wireguardMode: userspace is set explicitly (there is no automatic fallback); without wireguard-go the agent cannot bring up tunnels at all.

Why: The kernel lacks the module, or headers don’t match the running kernel.

Fix: sudo apt-get install wireguard (Debian/Ubuntu) or install kernel headers matching uname -r; alternatively install wireguard-go and set edgible config set wireguardMode userspace for userspace mode.

Related: EDG110, EDG114

EDG121 — IPv4 forwarding disabled (gateway device)

Section titled “EDG121 — IPv4 forwarding disabled (gateway device)”

What happened: /proc/sys/net/ipv4/ip_forward is 0.

Why: A gateway cannot route traffic to serving devices without IP forwarding.

Fix: sudo sysctl -w net.ipv4.ip_forward=1 && echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf. The gateway installer enables this during WireGuard setup.

EDG122 — Container without a working systemd

Section titled “EDG122 — Container without a working systemd”

What happened: This looks like a container, and systemctl is-system-running reports systemd is not functional.

Why: The systemd install method can’t manage the agent without a working systemd init.

Fix: Re-run the install with --type foreground, or run the container with a systemd init.

Related: EDG102

What happened: docker --version failed on a serving device (warning — the agent still installs).

Why: Docker and Compose workloads deployed to this device will fail until Docker is present.

Fix: Install Docker (https://docs.docker.com/engine/install/), then sudo systemctl enable --now docker.

On an agent installed under your own account, where Docker IS present, this also warns: the agent process itself is unprivileged, but the Docker daemon it talks to over the socket is not — access to that socket is administrator-equivalent on the host no matter how the agent was installed.

What happened: Another process holds WireGuard’s tunnel endpoint port.

Fix: Inspect with sudo ss -lunp 'sport = :51820', then stop or reconfigure the conflicting service (e.g. sudo systemctl disable --now <service>). A port held by the agent’s own stack is fine and passes automatically.

Related: EDG131, EDG132

EDG131 — Port 80/tcp already in use (gateway device)

Section titled “EDG131 — Port 80/tcp already in use (gateway device)”

What happened: Another process holds port 80, which the gateway needs for HTTP ingress (redirects to HTTPS). This check runs on gateway devices only — a serving device retires 80/443 entirely and listens on :10222 alone, so it never probes this port.

Why: TLS certificates come from the backend’s DNS-01 flow, not an HTTP-01 challenge, so this has never been about ACME — it’s the gateway’s plain-HTTP entry point.

Fix: Inspect with sudo ss -ltnp 'sport = :80', then stop or reconfigure the conflicting service (commonly nginx or Apache: sudo systemctl disable --now nginx).

Related: EDG130, EDG132

EDG132 — Port 443/tcp already in use (gateway device)

Section titled “EDG132 — Port 443/tcp already in use (gateway device)”

What happened: Another process holds port 443, which the gateway needs for HTTPS ingress. This check runs on gateway devices only — a serving device retires 80/443 entirely and listens on :10222 alone.

Fix: Inspect with sudo ss -ltnp 'sport = :443', then stop or reconfigure the conflicting service.

Related: EDG130, EDG131

EDG140 — Gateway mode requires root (agent is unprivileged)

Section titled “EDG140 — Gateway mode requires root (agent is unprivileged)”

What happened: The agent started as an ordinary user but its agent.config.json says deviceType: gateway. A gateway rewrites the host’s firewall rules, routing policy and kernel network settings and takes inbound traffic on 80/443 — all of which need administrator rights, so the agent refuses to start rather than come up half-working.

Fix: Install gateway devices with sudo (sudo edgible agent install), or change this device to a serving device. An agent installed under your own account supports serving devices only.

Related: EDG141, EDG142

EDG141 — Workload strategy requires root

Section titled “EDG141 — Workload strategy requires root”

What happened: An application deployed to this device asked for a workload type an agent running under an ordinary user account cannot run. A workload published as a system service writes system-wide unit files under /etc/systemd/system and secret files under /run/edgible/secrets — both administrator-only.

Fix: Deploy this application as a compose, managed-process, or pre-existing workload, or install this device’s agent with sudo.

Related: EDG140

EDG142 — No per-user service manager (install without sudo)

Section titled “EDG142 — No per-user service manager (install without sudo)”

What happened: Installing without sudo puts the agent in a per-user service (~/.config/systemd/user/edgible-agent.service, driven by systemctl --user), and this host has no per-user service manager to install it into — typically a container without systemd, or an SSH session with no XDG_RUNTIME_DIR/DBUS_SESSION_BUS_ADDRESS.

Fix: Log in on a real session on this machine, or start one for the account with sudo machinectl shell <user>@, then re-run. Over plain SSH, export XDG_RUNTIME_DIR=/run/user/$(id -u) first. If the host has no systemd at all, install with sudo instead: sudo edgible agent install.

This check is Linux-only. On macOS an install without sudo uses a LaunchAgent, and there is no per-user session manager to probe.

Related: EDG143, EDG122

EDG143 — The agent will not keep running after you log out

Section titled “EDG143 — The agent will not keep running after you log out”

This is a warning, not a failure — the install goes ahead. It is here so a device does not quietly go offline the next time you disconnect.

What happened (Linux): An agent installed under your own account is tied to your login session, so it stops when you log out (or when your SSH session ends) and does not start at boot.

Fix (Linux): One command, once per account:

Terminal window
sudo loginctl enable-linger <user>

That is the only place sudo appears in an install without it. Run it and the agent starts at boot and survives logout. Or install the agent as a system service instead: sudo edgible agent install.

What happened (macOS): Nothing is broken, and there is nothing to enable. macOS has no equivalent setting: an agent installed under your own account exists only inside a login session, so it starts when you log in and stops when you log out. This is reported as a warning rather than a green tick — a green tick would imply the device stays online — and rather than a failure, because no action on the host can change it.

Fix (macOS): If the device must stay online across logout and reboot, install it as a system service instead:

Terminal window
sudo edgible agent install

Related: EDG142, EDG145

EDG144 — Agent cannot configure the tunnel without administrator access

Section titled “EDG144 — Agent cannot configure the tunnel without administrator access”

What happened: The agent is running under an ordinary user account but its agent.config.json asks for a tunnel that needs administrator rights — kernel WireGuard, or a wireguard-go socket directory it cannot write. It refuses to start rather than loop forever failing to bring the tunnel up.

Why you are unlikely to see this: No install produces that combination. An install without sudo always configures the agent’s own built-in tunnel, which opens no network device and needs no privilege at all. This code is reached when agent.config.json has been edited by hand after the fact.

Fix: Remove the wireguardMode key from agent.config.json and restart the agent (edgible agent restart) so it goes back to the built-in tunnel. If this device genuinely needs kernel WireGuard, install it as a system service instead — uninstall first, the way it was installed:

Terminal window
edgible agent uninstall
sudo edgible agent install

Related: EDG116, EDG120

EDG145 — Agent already installed the other way on this host

Section titled “EDG145 — Agent already installed the other way on this host”

What happened: The install stopped before writing anything because this machine already has an agent installed the other way: a system service where you are installing under your own account, or one under a user account where you are installing with sudo.

Why: A machine can hold one agent. Two would fight over the same device — both reconciling the same applications, both trying to hold the same tunnel.

Fix: Remove the existing install first, run the way it was installed, then install again:

Terminal window
sudo edgible agent uninstall # if the message named a system service
edgible agent uninstall # if it named an install under a user account

The message names the exact service file it found, so you never have to guess which one it is. The device itself is unaffected — re-installing binds this machine to the same device again.

The uninstall works even if this CLI has no record of that install — a re-imaged or cleared CLI profile loses the record while the service itself stays on the machine. It then reports the install it found on this host and removes that.

Related: EDG143

What happened: The hostname of the download or API endpoint would not resolve.

Fix: Check this machine’s DNS (resolvectl status), and any VPN or proxy that rewrites DNS. If you overrode the endpoint (EDGIBLE_CLI_BASE_URL, EDGIBLE_DISTRIBUTION_URL), verify the value.

Related: EDG201

EDG201 — Connection failed (network or proxy)

Section titled “EDG201 — Connection failed (network or proxy)”

What happened: A download or connection attempt failed outright, or returned an unexpected HTTP status.

Fix: Check outbound HTTPS (443) connectivity and any HTTP proxy settings, then retry. If it persists, report it — the distribution channel may be misconfigured.

Related: EDG200, EDG204, EDG205

EDG202 — Download endpoint returned HTTP 403

Section titled “EDG202 — Download endpoint returned HTTP 403”

What happened: The distribution endpoint denied access to a release artifact.

Why: Either the artifact was never deployed or the distribution (CloudFront/S3) is misconfigured — this is a problem on Edgible’s side, not yours.

Fix: Please report it, including the URL from the error output.

Related: EDG203

EDG203 — Download endpoint returned HTTP 404

Section titled “EDG203 — Download endpoint returned HTTP 404”

What happened: The requested release manifest or bundle does not exist on the channel.

Why: Usually a pinned version that was never published.

Fix: Check EDGIBLE_CLI_VERSION / EDGIBLE_AGENT_VERSION and the base URL; omit them to install the latest release.

Related: EDG202, EDG401

What happened: The endpoint did not respond within the timeout.

Fix: Check connectivity and firewall rules for outbound HTTPS (443), then retry.

Related: EDG201

What happened: curl could not complete a TLS handshake with the endpoint.

Why: Usually a proxy intercepting TLS, missing/stale CA certificates, or a badly skewed system clock.

Fix: Ensure ca-certificates is installed and current, check the system clock, and check for TLS-intercepting proxies.

Related: EDG211

What happened: The Edgible API did not answer at all (any HTTP response, even an error status, counts as reachable).

Fix: Check outbound HTTPS (443) from this host to the API host, and any proxy/firewall egress rules.

Related: EDG304

EDG211 — Host clock skewed against the Edgible API

Section titled “EDG211 — Host clock skewed against the Edgible API”

What happened: This host’s clock is significantly off from the API’s (over ~30s warns, over ~120s fails).

Why: Skew breaks request signing, device authentication, and TLS validation.

Fix: sudo timedatectl set-ntp true (or sudo chronyc makestep), then re-run.

Related: EDG303, EDG205

EDG220 — CLI session token missing or expired

Section titled “EDG220 — CLI session token missing or expired”

What happened: No Edgible session token was found on this machine, or it has expired.

Fix: Run edgible auth login.

Related: EDG221

What happened: The device ID/password this host presented were rejected by the platform.

Fix: Re-enroll with fresh credentials (edgible agent enroll) and verify the host clock is in sync — a skewed clock fails auth the same way.

Related: EDG220, EDG303, EDG211

What happened: The agent service is not running — it failed to start or crashed immediately.

Fix: Inspect the crash: journalctl -u edgible-agent -n 100 or edgible agent logs. The diagnostics file written next to the install output captures the same evidence.

Related: EDG302

EDG302 — Agent started but never wrote its status file

Section titled “EDG302 — Agent started but never wrote its status file”

What happened: The agent process started but crashed before finishing initialization (no status.json within the wait window).

Fix: Check edgible agent logs (or the service’s stderr.log) for the first error after startup, and re-run edgible doctor.

Related: EDG301

EDG303 — Device authentication rejected by the backend

Section titled “EDG303 — Device authentication rejected by the backend”

What happened: The agent started, but the backend rejected this device’s credentials.

Fix: Re-check EDGIBLE_DEVICE_ID/EDGIBLE_DEVICE_PASSWORD (or re-run edgible agent enroll with fresh credentials) and verify the host clock is in sync (sudo timedatectl set-ntp true) — see EDG211.

Related: EDG211, EDG221

EDG304 — WebSocket control channel unreachable

Section titled “EDG304 — WebSocket control channel unreachable”

What happened: The device authenticated, but its WebSocket control channel to the backend never connected.

Fix: Allow outbound HTTPS (443) to the Edgible API/WebSocket host from this device — corporate proxies and egress firewalls are the usual cause.

Related: EDG210

EDG305 — Agent healthy locally but backend never saw it online

Section titled “EDG305 — Agent healthy locally but backend never saw it online”

What happened: Everything looks healthy on the device, but the backend never reported it online within the wait window.

Fix: Give it a minute and check edgible device list. If it stays offline, run edgible doctor and contact support with the diagnostics file.

Related: EDG310

EDG306 — WireGuard handshake absent or stale

Section titled “EDG306 — WireGuard handshake absent or stale”

What happened: The control plane is up, but no WireGuard peer handshake completed — the data tunnel is dead.

Fix: First rule out a local cause on the device itself: edgible application get <app> shows the device’s tunnelFault — interface_create_failed means the WireGuard interface or its userspace binary never came up on this device (see EDG115 and EDG114), and no amount of network work will help. edgible doctor on the device surfaces the same local causes. Only once the interface is up, look at the path: allow outbound UDP 51820, and if the gateway and this device sit behind the same NAT, the router likely lacks hairpin support — see the troubleshooting guide for workarounds.

Related: EDG115, EDG130, EDG120

EDG310 — Backend verification skipped (no API connectivity from this machine)

Section titled “EDG310 — Backend verification skipped (no API connectivity from this machine)”

What happened: The install verified locally, but the machine running the CLI could not reach the Edgible API to confirm the device is visible. This is a warning, not a failure.

Fix: Run edgible device list from a machine with API access, or edgible doctor here once connectivity returns.

Related: EDG305, EDG210

EDG401 — Release manifest missing or invalid

Section titled “EDG401 — Release manifest missing or invalid”

What happened: The channel’s release manifest (<version>.json) could not be fetched, or is missing required fields (version, sha256). When a signing key is baked in, installs fail closed rather than proceed unverified.

Fix: Check EDGIBLE_CLI_BASE_URL / EDGIBLE_AGENT_VERSION; omit them to install the latest release. If unchanged defaults fail, report it.

Related: EDG203, EDG403

EDG402 — Bundle sha256 checksum mismatch

Section titled “EDG402 — Bundle sha256 checksum mismatch”

What happened: The downloaded bundle’s checksum did not match the release manifest. Nothing was installed — an existing install is untouched.

Why: The download is corrupt or has been tampered with.

Fix: Retry the install. If it persists, report it — do not bypass the check.

Related: EDG403

EDG403 — Manifest signature verification failed

Section titled “EDG403 — Manifest signature verification failed”

What happened: The release manifest’s signature did not verify against the baked-in signing key (or the manifest was unsigned while a key was pinned). The install refused to proceed.

Fix: Retry once (a partially propagated release can race). If it persists, report it immediately — do not work around a signature failure.

Related: EDG402, EDG401

EDG404 — Bundle entry point missing after extraction

Section titled “EDG404 — Bundle entry point missing after extraction”

What happened: The bundle extracted, but its entry point (dist/index.js or the vendored SDK) is missing — a bad artifact. The installer refused to activate it.

Fix: Re-run the install to fetch a fresh copy. A previous version (if any) is still under <prefix>/versions — re-point <prefix>/current at it to roll back manually.

Related: EDG405, EDG402

What happened: unzip failed while extracting the downloaded bundle.

Fix: Check free disk space at the install prefix and that unzip works, then re-run the installer.

Related: EDG104, EDG106

What happened: The new version unpacked, but the installer could not swap the current symlink to activate it. The previous install keeps working.

Fix: Check permissions and filesystem state at <prefix>/current, then re-run the installer.

Related: EDG101, EDG407

What happened: The installer could not write the edgible launcher into the bin directory.

Fix: Check the bin dir is writable (/usr/local/bin system-wide, ~/.local/bin user), or set EDGIBLE_CLI_BIN_DIR to a writable directory and re-run.

Related: EDG101, EDG406

What happened: Writing the agent’s files (bundle, config directory contents) onto the host failed.

Fix: Check disk space and permissions on the agent config directory, then re-run the install with sudo.

Related: EDG101, EDG104

EDG411 — Agent config invalid after write

Section titled “EDG411 — Agent config invalid after write”

What happened: The agent configuration failed validation immediately after being written.

Fix: Re-run the install (it rewrites the config from your inputs). If it persists, report it with the install output.

Related: EDG410

What happened: Installing or reloading the agent’s service unit (e.g. the systemd unit) failed.

Fix: Re-run with sudo, then check systemctl daemon-reload and journalctl -u edgible-agent for the underlying error.

Related: EDG102, EDG301

EDG500 — No install manifest (dev checkout or legacy install layout)

Section titled “EDG500 — No install manifest (dev checkout or legacy install layout)”

What happened: edgible upgrade (or edgible uninstall) could not find install-manifest.json, so this CLI was not installed by the installer.

Fix: Reinstall with curl -fsSL https://get.edgible.com/install.sh | bash — subsequent upgrades will then work in place. Dev checkouts update via git pull, not upgrade.

Related: EDG501

EDG501 — Could not fetch the latest-version manifest

Section titled “EDG501 — Could not fetch the latest-version manifest”

What happened: edgible upgrade could not fetch or parse the release channel’s version manifest.

Fix: Check outbound HTTPS (443) to get.edgible.com and retry. If your install uses a custom channel, verify its base URL in <prefix>/install-manifest.json.

Related: EDG401, EDG201

EDG502 — Install prefix not writable for upgrade

Section titled “EDG502 — Install prefix not writable for upgrade”

What happened: This CLI was installed system-wide and the current user cannot write the install prefix or launcher dir.

Fix: Re-run with elevated privileges — edgible upgrade prints the exact sudo env EDGIBLE_CLI_VERSION=… bash -c "curl … | bash" command to copy-paste.

Related: EDG101, EDG500

What happened: The uninstaller found no install at the expected prefix and no launcher.

Fix: If you installed to a custom location, set EDGIBLE_CLI_PREFIX / EDGIBLE_CLI_BIN_DIR to match and re-run. For non-interactive removal, add --yes: curl -fsSL https://get.edgible.com/install.sh | bash -s -- --uninstall --yes.

Related: EDG500

These carry a named code rather than an EDG number — the first five come back from the API when a deploy tries to cut a release whose code artifacts don’t line up, and the last two are stamped on the device’s deployment state when a release can’t be realized. In normal use edgible stack deploy produces all of the pieces itself, so most of these mean a hand-crafted apply or an interrupted deploy.

What happened: A code[] entry reached the cut with no artifact.digest.

Why: Applying a declaration is cutting a release, and a release must pin the exact bytes every code archive delivers. The digest is stamped by the deploy tooling when it packs and ships the directory.

Fix: Run edgible stack deploy, which packs, ships, and pins in one pass. The message names the workload and the entry.

Related: CODE_ARTIFACT_REF_MISSING

What happened: A code[] entry is declared, but no matching artifact reference was supplied with the apply.

Why: Each code archive’s digest lives in two places — the entry the agent mounts from, and the release’s pinned artifact list, which is what registration and retention read. A canonical entry with no pinned reference would sign code bytes the artifact ledger never sees.

Fix: Ship the archive and supply its reference on the apply — edgible stack deploy does both.

What happened: The apply pinned a code artifact reference (role <workload>/code/<entry>) that no code[] entry declares.

Why: The two sides must agree in both directions; an orphan reference would retain a blob nothing mounts.

Fix: Remove the stale reference, or declare the entry it names. Re-running edgible stack deploy from your stack file regenerates a consistent pair.

What happened: A pinned code artifact reference names a different digest than the code[] entry it belongs to.

Why: The signed release manifest and the bytes the agent mounts must be the same bytes. Without this check an apply could sign one digest and pin another.

Fix: Re-run edgible stack deploy so the pack, the ship, and the pin all come from the same tree.

What happened: A code artifact reference was pinned with an artifact kind other than archive.

Fix: Code archives are always kind archive. Re-run edgible stack deploy.

What happened: The device could not realize a release because a code[] archive it pins was never delivered to that device. The workload is not started — the agent fails closed rather than mounting nothing.

Why: Code archives are pushed by the CLI to the devices assigned at the time of the deploy. A device added to the application afterwards was never pushed to.

Fix: The message carries it — run edgible stack deploy again with the device assigned, to re-ship the code artifacts to it. See Ship code without rebuilding the image.

What happened: The device refused to extract an archive. Nothing was partially extracted.

Why: Extraction is bounded and fail-closed. An archive is refused if it exceeds 100,000 entries or 2 GiB of unpacked bytes, contains absolute paths or .. segments, has a symlink pointing outside the extracted tree, or contains entry types other than files, directories, and symlinks.

Fix: Point code[].path at the source tree you actually serve rather than a whole project directory, and remove any symlinks that escape it. The message names the offending entry.

Two more named code values worth recognising. Neither is a code-artifact problem, so they sit apart from the section above.

What happened: A stop or teardown could not fully remove the application’s workloads. The deployment state goes to error with this reason and the per-workload messages beside it, naming which workload refused to stop.

Why: A compose down or a process kill failed, so containers or ports may still be held on the device. The agent reports it rather than recording a clean stop over something that is still running — and it deliberately skips purging the application’s storage, because a live container still holds its mounts.

Fix: Read edgible application get <app> for the workload names in the failure, then look at what is still up on the device (docker ps, or the process’s own supervisor). Clear it, and re-run the teardown or delete — the agent keeps the application registered so a later reconcile can retry.

What happened: A 403 from POST /jobs — the job type you asked for cannot be created through the API.

Why: Most job types are internal orchestration steps the control plane sequences itself (migration phases, storage promotion, workload teardown and restart, config updates). Dispatching one out of band drives a device through a phase its orchestrator is not expecting. Only diagnostics collection, agent self-update and plugin jobs are dispatchable by a person.

Fix: Use the command that owns the operation — edgible application redeploy, edgible application storage promote, edgible stack teardown, the migration verbs — rather than dispatching its job directly. Creating any job also needs EDITOR access to the target device’s organization; a READ_ONLY member gets a 403 naming that instead.