Skip to content

Diagnose a broken app

Something is wrong: the app returns errors, or the page never loads over HTTPS. A short self-diagnosis flow tells you where the problem is: edgible application logs reads what your workload is printing, edgible certs reads the state of its TLS certificate, and — for owners — edgible device logs reads the device agent’s own journal when the workload logs are empty. This guide walks through all three.

Before you start, have the application’s ID handy:

Terminal window
edgible application list

Before working through the layers by hand, run the composed triage. edgible application doctor runs every check below — deployment status, certificates, the data-path trace, and workload log collection — in path order and prints a single Verdict naming the first failing layer, its evidence, and the exact follow-up command to run next:

Terminal window
edgible application doctor --app-id <app-id>

It exits 0 when it finds no faults and 1 when it diagnoses one, so it also works as a scriptable health gate (add --json for the machine-readable verdict, findings, and raw checks; --timeout <ms> bounds the data-path trace). A check that can’t run itself — say the device is offline so its logs can’t be read — is reported as unavailable and is never turned into a fabricated fault.

The Verdict points you at the right section below. The rest of this guide is the manual path doctor automates — read on when you want to look at a single layer directly, or when the verdict sends you into one of them.

edgible application logs collects the live stdout/stderr from the serving device(s) hosting your app, on demand, over the diagnostics channel. This is what your workload itself is printing — a crash loop, a stack trace, a “connection refused” from a dependency, a port it never bound. It reads only your app’s own workloads (its systemd unit or its compose project) — never the output of other applications sharing the device. Any organization member can read them.

Terminal window
edgible application logs --app-id <app-id>

When the default output is too quiet, drop the priority floor to see everything the workload emitted:

Terminal window
edgible application logs --app-id <app-id> --priority debug

--priority (debug, info, warning, err; default info) sets the minimum severity for journald-backed workloads — a managed process or systemd unit. Docker Compose containers have no priority concept, so the flag has no effect on them. Note that managed-process output is captured in memory and starts fresh when the agent restarts, so a recent agent restart can explain an empty buffer.

Look at a specific window, or cap how many lines come back per device:

Terminal window
edgible application logs --app-id <app-id> --since 2026-07-06T12:00:00Z --limit 100

--since accepts an ISO-8601 timestamp or epoch milliseconds. -n/--limit bounds the number of lines returned per device.

Stream new lines as they arrive — useful while you reproduce the failure:

Terminal window
edgible application logs --app-id <app-id> --follow

If the app is deployed across more than one serving device, output comes back in per-device blocks. A block can report one of two unavailable states, and they mean different things:

  • offline — the device isn’t connected, so the collection job was never dispatched. Nothing was even attempted; get the device back online (see device logs below).
  • collection failed: <error> — the device is reachable but reading its logs failed. The job ran and errored; the message is the read failure.

Narrow the output to a single device:

Terminal window
edgible application logs --app-id <app-id> --device <serving-device-id>

Add --json for machine-readable output you can pipe into jq.

In the webapp, the same output is the Logs tab on the application page, with a priority selector matching --priority. (Don’t confuse it with the Events tab, which is the lifecycle stream described below — a different thing.)

While a deploy is in flight, the webapp application Overview shows a live deploy timeline — each phase, how long it took, and, when a phase fails, the same failure evidence the CLI prints (including the HEALTH_CHECK_FAILED probe line and body snippet). It polls on its own during an active deploy, so you can watch a deploy converge or fail without re-running a command.

If the logs are empty or the workload never appears, the problem is likely upstream of the workload — the app may be suspended, the hostname unknown, or the request may be filtered before it reaches your device. See Why can’t I reach my app? for that class of failure.

application logs is the workload’s own output. For the platform’s record of what happened to the application — deploys, state changes, failures the platform observed — use the historical lifecycle stream instead:

Terminal window
edgible application events --app-id <app-id>

Read the device agent’s own logs (owner)

Section titled “Read the device agent’s own logs (owner)”

If the workload logs come back empty, the device shows as offline, or an app simply won’t converge, the next place to look is the edgible-agent daemon’s own journal — what the agent itself is doing (enrollment, connection, reconcile), independent of any workload:

Terminal window
edgible device logs --name <device-name>
edgible device logs --device-id <device-id> --priority warning --limit 200

This is organization-owner only — a member gets a clear agent logs require organization owner access message. Like workload logs, it distinguishes an offline device (job never dispatched) from a collection failed: <error> (reachable, read failed). In the webapp this is the owner-only Agent Logs tab on the device page.

If HTTPS refuses to connect, or the browser reports a certificate error, the workload may be perfectly healthy while the certificate for its hostname is still provisioning or has failed to issue. edgible certs reports the certificate state, expiry, and last failure reason per hostname.

certs is a top-level command — not a subcommand of application. With no flags it enumerates certificates across every application in your active organization:

Terminal window
edgible certs

Narrow it to one application with -a/--app:

Terminal window
edgible certs --app <app-id>

Add --json for scripting.

Read the state per hostname:

  • A hostname that is still validating just needs time — DNS and issuance take a moment after you first publish a hostname. Give it a minute and re-run.
  • A hostname whose issuance has failed reports a classified last failure reason:
    • DNS_VALIDATION_FAILED — the DNS-01 challenge never validated. The hostname has to resolve to the Edgible edge; confirm it resolves, then let the platform retry.
    • CA_REJECTED — the certificate authority declined the order for another terminal reason (for example a rejected CSR). The provider’s error detail is shown alongside.

A deploy that is waiting on a certificate fails fast with the same named reason once issuance is terminally failed — you won’t sit through a silent 30-minute wait on a certificate that will never issue.

For the DNS-and-issuance side of custom hostnames, see Use a custom domain.

A quick triage order when an app is broken:

  1. edgible application doctor --app-id <app-id> — run this first. It composes every step below into one verdict and tells you which layer failed and what to run next. Drop to the manual steps when you want to inspect a layer directly.
  2. edgible application logs --app-id <app-id> --priority debug (add --follow and reproduce) — watch what the workload prints. A crash or error here is a workload problem. An empty result at debug means the workload never produced output.
  3. edgible certs --app <app-id> — is the certificate ready? A DNS_VALIDATION_FAILED / CA_REJECTED here means HTTPS failures are a TLS problem, not a workload problem.
  4. edgible device logs --name <device> (owner) — if workload logs are empty or the device reads offline, check the agent’s own journal to see whether the device is enrolled, connected, and reconciling.
  5. edgible application events --app-id <app-id> — if none of the above explains it, check what the platform recorded happening to the application.
  6. If nothing reaches the workload at all, work through Why can’t I reach my app? — the failure is at the edge, not in your code.