Identify the failed stage before reinstalling anything

The OpenClash message “core update failed” describes an outcome, not a cause. The project’s openclash_core.sh first obtains version metadata, constructs a download for the configured CPU model and core type, writes a compressed file to a temporary location, tests it with gzip, extracts it, grants execution permission, asks the candidate binary for its version, and only then moves it to the production path. A failure anywhere along that chain may be summarized by the same LuCI notification.

Save the complete log before retrying. Record the time, OpenClash version, current core version, router model, actual CPU architecture, selected core type, and whether small-flash mode is enabled. The last red line alone is rarely enough. A missing version document, a curl name-resolution error, a truncated gzip file, an executable-format error, and a read-only target are different incidents with different remedies.

StageTypical evidenceFirst checks
Version lookupmetadata unavailable or emptyclock, DNS, HTTPS, source reachability
Downloadcurl DNS, connection, TLS, or HTTP errorrouter-side network path and response
Archive testgzip test failed or implausibly small filecomplete transfer versus an HTML error page
Candidate executionno version output or format errorCPU architecture, file type, permission
Move or launchmove failed or immediate exitspace, read-only mount, ownership, configuration

Keep the experiment narrow: do not upgrade OpenWrt, replace DNS, reinstall the plugin, and upload a binary during the same attempt. One controlled change preserves the meaning of the next log.

Verify the version source, DNS, and HTTPS path from the router

When the log stops at metadata or download, test from OpenWrt itself. A laptop browsing normally does not prove that the router process has working DNS, a default route, or trusted time. Confirm the date, time zone, and NTP synchronization first; a badly wrong clock can break certificate validation. Then distinguish name resolution from transport. A resolver failure produces no usable destination address, while a timeout may occur after resolution because the route, firewall, or remote endpoint does not complete the connection.

Issue 5098 contains one concrete sequence: curl: (6) Could not resolve host: fastly.jsdelivr.net, followed by a Smart core version-check failure. That report is useful evidence for that incident, not a universal diagnosis. If your own log reports HTTP 404, a TLS error, no space, or a gzip failure, follow the evidence you actually have rather than copying a DNS fix.

  1. Check the router clock, time zone, NTP status, and current WAN gateway.
  2. Test whether the exact update hostname resolves and whether TCP 443 is reachable.
  3. Make sure router DNS does not depend on an OpenClash core that is currently stopped.
  4. Inspect the response type and size so an error document is not treated as a core archive.
  5. After correcting the path, retry once and compare the stage reached in the new log.

A parent router, domain filter, custom resolver, or egress firewall can affect only the router’s update request. Create a specific, reversible direct path for testing instead of disabling every security rule. Restore the policy afterward and retain both logs. If several mirrors are configured, note which URL the script actually selected rather than assuming the first name visible in the UI.

A plugin Release is only a dated reference point. For example, OpenClash v0.47.156 records that release and its changes; it does not require every device to upgrade, and it does not prove that any separately downloaded core matches a particular router.

Match CPU architecture, core type, and the actual downloaded asset

If the transfer succeeds but the candidate cannot print a version, inspect architecture next. The update script uses the configured core_version CPU model and treats core targets separately. A retail router name is not an architecture identifier, and revisions sold under the same family may use different instruction sets. Compare the architecture reported by OpenWrt, the package manager architecture, and the file information of the old binary that already runs.

Do not confuse an archive, an executable, and a core family. The downloaded object may enter the temporary directory as gzip data and become an executable only after the integrity test and extraction. Renaming a compressed object to clash_meta does not extract it. Adding execute permission cannot make a binary for another platform compatible. An Exec format error, illegal instruction, or empty version result should send you back to asset selection.

Preserve provenance: obtain a manual candidate only from a first-party location linked by the project, and retain its original asset name and release context. A renamed third-party copy removes the clues needed to verify architecture and compression.

Keep the working old core in a controlled backup directory and record its version output and size. Validate the new candidate in a temporary directory: the file type matches the device, gzip testing succeeds, extraction produces a non-empty file, execution permission is present, and the version command returns normally. Only after all five checks should the production target be considered.

If the interface exposes Meta, Smart, or another choice, confirm that the installed OpenClash version supports it and that your configuration expects it. Plugin updates and core updates are related but separate. Updating firmware, packages, plugin, and core together may hide an incompatibility and removes a simple rollback.

Check temporary space, small-flash behavior, permissions, and file use

A complete download can still fail before installation. The script needs space for the compressed object, the extracted candidate, and the final target. Both the temporary filesystem and destination must therefore have capacity. It also contains a small_flash_memory branch: a normal setup targets a persistent OpenClash directory, while small-flash mode can place clash_meta beneath /tmp. That memory-backed location has different capacity and persistence characteristics and is cleared by reboot.

Inspect free bytes and inodes, then determine whether overlay or the destination mount has become read-only. A missing directory, wrong ownership, absent execute bit, or still-running process may fail at the final move or launch. Do not create space by deleting the only core known to work. First verify a backup, then remove only temporary objects that are positively identified as failed downloads.

  • Capacity: temporary storage must briefly hold both compressed and extracted files.
  • Permission: the directory must be writable and the candidate executable with appropriate ownership.
  • Process state: stop and start through the normal service flow rather than overwriting an active target.
  • Persistence: a small-flash temporary core must be recreated by the intended startup process after reboot.
  • Integrity: a plausible file size is not enough; archive and version checks must also pass.

If the move fails, inspect both the candidate and production path before rebooting. When the old binary is still intact, leave it in place and continue diagnosis. If a bad candidate has already replaced it, stop the service and restore the verified backup. Record each transition so that “old working,” “new staged,” and “new active” never become ambiguous.

Use a minimal manual recovery and verify the whole service path

Consider manual installation only after repeated automatic failures have been narrowed to a known stage and the source, architecture, and core type are established. Preserve the current binary instead of overwriting the sole copy. Obtain the exact candidate through a first-party route, then perform decompression, permission, and version checks in a temporary directory. Stop OpenClash, save the production target, and make one controlled replacement. The correct path and filename come from the script and UI in your installed version, not from a tutorial for another firmware image.

  1. Export configuration and copy the running core; record its version and size.
  2. Verify source provenance, CPU architecture, core family, and compression format.
  3. Test gzip, extraction, execute permission, and version output in staging.
  4. Stop the service, preserve the production target, and install the verified candidate once.
  5. Start the service and inspect core version, configuration load, groups, DNS, and a real connection.
  6. On failure, stop the service, restore the old binary, and analyze the sanitized log.

A new number in LuCI is not sufficient proof. The process should remain alive, parse the configuration, populate policy groups, avoid a router-DNS dependency loop, and handle client traffic as intended. Watch the log long enough to rule out a crash-and-restart cycle. Keep the old core until a reboot and a practical network check have both passed.

A repeatable order: log stage, network and metadata, architecture and type, archive validation, storage and permission, replacement and launch. Every result either identifies the fault or safely narrows the next check.

For a useful report, include both versions, CPU architecture, core type, failure time, and a sanitized log. Remove public IPs, subscription URLs, credentials, and the management address.

Official sources and version scope

Version numbers, filenames, and interface labels can change. Confirm them in the linked project documentation before making changes.