Connectivity Troubleshooting · Clash Technical Blog

Mihomo 0ms test failure: v1.19.33 fix

Mihomo connects, but latency tests fail and the history shows 0ms? Check for the timing bug below 1 millisecond, confirm the running core, get the v1.19.33 fix through a supported update, and retest the same target with a rollback ready.

  • Mihomo
  • v1.19.33
  • 0ms
  • URLTest
  • Latency tests
On this page

You select a proxy manually and websites load, yet its latency test fails and automatic selection avoids it. Before importing the subscription again, check a specific Mihomo timing bug: a successful test taking less than 1 millisecond could have its duration truncated to 0.

Why does the test fail when the proxy works?

Upstream report #3316 describes an apparent contradiction: the same proxy has alive: true and delay: 0 in its history, while its individual delay endpoint returns 503. An automatic group may also treat that 0 as a missing measurement. The affected test target is typically on the same host, the local network or a nearby edge; this does not explain every failed test.

A graphical client may display different core errors as a generic failure or timeout, without showing 0ms. A Timeout message alone, or alive: true alone, does not establish this bug. Compare results for the same proxy and test URL at roughly the same time.

Distinguish three similar-looking problems

What you observeWhat to check next
The test finishes quickly, but the old core records 0 alongside a failureCheck whether the timing scenario in #3316 fits, then obtain the fix through a supported channel.
DNS, TLS or connection errors, or a request that really exceeds timeoutFollow the relevant logs. The sub-millisecond fix does not explain every timeout.
A group stops switching after a Provider refresh, without the timing evidence aboveKeep the records from that time and investigate the group state separately. Do not treat it as the same resolved bug.

v1.19.33 changes measurement, not network speed

The v1.19.33 release notes include #3316. In the pinned source, the normal URLTest return path converts elapsed time to whole milliseconds, then replaces 0 with 1. This keeps a valid measurement distinct from the 0 used for a missing delay. With unified-delay enabled, the timing of a successful second request goes through the same final adjustment.

This 1ms value is a measurement floor. It does not mean the network took exactly 1 millisecond, and it promises no speed increase. The test still involves establishing a connection, making an HTTP request and checking any configured status-code requirement. The target, proxy and client still need their own checks.

Increasing timeout only changes how long a test can wait; tolerance controls when an automatic group switches. Neither recovers the valid timing lost when a result is truncated to 0. Do not keep changing these two settings to judge whether this fix works.

Record which proxy and URL are failing

Menu names vary by client. Use its existing core-information screen, startup logs, proxy test and connection records. There is no need to enable external-controller, expose a port or share a secret just for these checks. The client version is not a substitute for the version of Mihomo actually running.

Match test results to actual connections

  1. Confirm the running core and active configuration

    Record the full version from the core-information screen or the current startup log, along with the active configuration, proxy name and test URL. A core executable in another directory does not prove which version the client is running.

  2. Separate individual tests, automatic groups and Provider checks

    Inspect the active configuration for the test entry point, url, timeout, interval, expected-status and unified-delay. A group uses its url to test its proxies; a Provider included through use has a separate health check. Do not assume they test the same target.

  3. Repeat a few tests under the same conditions

    Select the same proxy and run the client's existing individual test. Then check the connection records to confirm that an actual request used it. Record the time and error. Loading a website and completing the latency-test request are separate observations.

  4. Use only the evidence you can actually see

    If existing local diagnostics expose delay/history, compare the 0 value and failure for the same proxy and URL. Otherwise, save the screen and logs and mark the cause as unconfirmed. A Timeout label in the UI does not reveal a sub-millisecond duration.

If the test URL returns a status outside expected-status, or logs show a name-resolution, certificate or connection error, address that specific cause first. Do not set up a service, flood it with tests or disable certificate validation to manufacture a result below 1ms.

Install the fix and confirm it is active

First keep independent backups of the configuration, client data and a restorable copy of the current version. If the app supports separate core updates, use an approved stable channel to get a version containing #3316. Otherwise, use a stable client package whose maintainer confirms that it includes the fix. Do not overwrite files inside the app.

Keep the test conditions consistent after updating

  1. Check that the new core really started

    v1.19.33 is confirmed to contain the fix. After updating and restarting as the client requires, read the core information or new startup log again. An update-success notification alone is not enough.

  2. Retest the same proxy against the same target

    Restore the same configuration and test URL. Run the individual proxy test first, then observe the original automatic group or Provider check. Compare each entry point separately; results from different targets are not a valid before-and-after comparison.

  3. Check the requests you actually use as well

    Confirm that the client's connection records still point to the intended proxy, then retry a website or app request that worked before. If existing diagnostics expose it, check that a valid measured duration recorded as 0 no longer causes the false failure. Do not expect every proxy to show 1ms.

If no supported package containing the fix is available yet, you can temporarily select the proxy manually after confirming that it really works. This does not fix the timing or prove that automatic failover has recovered. If you cannot confirm usability, keep the original configuration and wait for a stable update; do not delete the subscription or rewrite the whole configuration.

What counts as a completed check?

Check each item, not just a green number

  • You have recorded the full version of the running core and confirmed the update channel and configuration actually loaded.
  • Before-and-after tests use the same proxy and test URL, with the status-code requirements and time units for each test entry point understood.
  • You did not also change DNS, TLS validation, timeout, tolerance or the subscription and then mistake those changes for the effect of this fix.
  • You have rechecked the original individual test and actual requests. Automatic-group and Provider health checks were observed separately; one manual test was not treated as proof that everything recovered.
  • If failure remains, you have saved the specific error, time and redacted results, distinguishing real timeouts, status-code mismatches and Provider-refresh problems.

This explanation is based on the upstream fix and pinned source. No core was downloaded and no test was run in your environment. If a failure remains after updating, follow the new, specific error. v1.19.33 is not a promise to solve every latency-test problem.

How to recover if the update causes other problems

Stop the affected operation. Use the original supported update method to restore the saved version, then restore its matching independent backup. Do not let two versions write to the same data directory or overwrite your only backup. After restoring, check the running core, configuration, manual selection and actual requests.

Rolling back may bring the timing bug back; it is a way to recover a usable setup. When reporting the remaining issue to the maintainer, include the operating system, full core version, test entry point, redacted URL, time and exact error. Remove subscription tokens, control keys and private information. A closed issue alone does not prove that your package contains the fix.

References