I'm sad to report that blocking timers in TRAMP is not sufficient to avoid it breaking other operations: process filters can also run while TRAMP is sending, and waiting for the result of, a command.
I have attached a backtrace showing this, which happens during startup: I trigger an async ELPA package refresh at the start of my init file, which is what causes the HTTPS connection, and in the process filter invokes the NSM library to verify the cert – and that tries to access a local path for the database of ... something related to handling certificates. (I think user supplied policy decisions around them or something, but I don't know the detail.)
That call to NSM from `url-https-proxy-after-change-function` in `url-http.el`, ultimately called from `url-http-generic-filter` with `funcall`, which is set as the process filter for the network connection in `url-http`, the entry point to fetching the content.
I found this when I set down to discover why my package refresh was breaking during startup; if it is still running when the desktop.el library triggers restoring state, and that state includes TRAMP files (which it always does, for me) then it can happen at the same time as the refresh.
A reproducible case should be possible by way of running this code in a TRAMP backed buffer:
(progn (package-refresh-contents t) (revert-buffer)) ;; the first bit starts an async package refresh
It is, though, a race condition, so if it doesn't trigger you may want to loop reverting or something. The backtrace is fairly clear, however. In theory it could also be triggered by any other process filter that triggers a file operation on a local file.
Notes on the backtrace:
address@hidden is my advice to capture the backtrace, and consists of calling (debug) at the appropriate moment.
I censored some names in the source for work related reasons, which are a) fairly obvious, and b) only in strings, and c) not relevant to the bug itself.
The `gssh` method is a copy of the `ssh` method with a trivial modification; while I don't think it is strictly relevant, the performance of it may be related to how easy the race is for me to hit.
The modification consist of pointing at the "correct" ssh binary for my environment, by absolute path, rather than the default one. (I think I fixed the problem causing it to come into being by adjusting how I handle the executable-path in init.el too, but I'm too lazy to remove the configuration now.)