docmirror/dev-sidecar · warning
[speed] test error: ${this.hostname} ➜ ${item.host}:${this
Error message
[speed] test error: ${this.hostname} ➜ ${item.host}:${this.port} from DNS '${item.dns}', errorMsg: ${e.message} What it means
SpeedTester._doTest logs a warning when testing a candidate IP (host:port for a domain, via a specific DNS provider) throws and the failure is not a timeout. The candidate item is marked status 'failed' with the error as its title; the tester then moves on to other backups, so overall IP selection usually still succeeds.
Source
Thrown at packages/mitmproxy/src/lib/speed/SpeedTester.js:224
} finally {
this.isTestingBackups = false
}
}
async _doTest (item, aliveList) {
try {
const ret = await this.testOne(item)
item.title = `${ret.by}测速成功:${ret.target}`
log.info(`[speed] test success: ${this.hostname} ➜ ${item.host}:${this.port} from DNS '${item.dns}'`)
_.merge(item, ret)
aliveList.push({ ...ret, ...item })
} catch (e) {
if (item.time == null) {
item.title = e.message
item.status = 'failed'
}
if (!e.message.includes('timeout')) {
log.warn(`[speed] test error: ${this.hostname} ➜ ${item.host}:${this.port} from DNS '${item.dns}', errorMsg: ${e.message}`)
}
}
}
testByTCP (item) {
return new Promise((resolve, reject) => {
const { host, dns } = item
const startTime = Date.now()
let isOver = false
const timeout = 5000
let timeoutId = null
const client = net.createConnection({ host, port: this.port, family: host.includes(':') ? 6 : 4 }, () => {
isOver = true
clearTimeout(timeoutId)
const connectionTime = Date.now()View on GitHub (pinned to 7710cd56cc)
Solutions
- Check the errorMsg in the log: ECONNREFUSED/EHOSTUNREACH means the candidate IP is dead — remove or update it in dns/providers or preset IP config
- If the DNS provider failed, switch to a reachable one (e.g. aliyun/google) in config
- Verify no local firewall blocks outbound connections to the tested port
- Nothing to fix if other backups pass — this is expected failover behavior; the fastest working IP is still chosen
Defensive patterns
Strategy: retry
Try / catch
try {
await tester.testOne(candidate)
} catch (e) {
if (!String(e.message).includes('timeout')) {
log.warn('candidate unreachable, trying next backup', e.message)
}
// tester already marks item failed; proceed to next backup
} Prevention
- Refresh preset/backup IP lists periodically — stale IPs are the main cause
- Configure multiple DNS providers so a dead DoH/DoT endpoint doesn't fail all probes
- Ignore non-timeout warnings when other backups succeed — failover is by design
- Check RequestCounter stats (3 consecutive errors / <40% success) to see if a backend is flapping
When it happens
Trigger: During testBackups → _doTest, connecting to a candidate IP throws a non-timeout error: ECONNREFUSED (IP dead/blocked), EHOSTUNREACH, TLS handshake failure for https probes, or DNS resolution failure for item.dns.
Common situations: Preset/backup IP lists going stale (IPs no longer serving the domain); GFW/ISP blocking certain IPs; DoH/DoT provider unreachable; firewall on the local network blocking the probe port.
Related errors
- [speed] test by TCP error:
- [speed] test by TCP timeout:
- 下载远程配置成功,但内容为空:
- 下载远程 domestic-domain-allowlist.txt 文件成功,但内容为空或内容太短,判断为无效的 do
- IPv6 地址 ${ip} 多次不可达(ENETUNREACH),已自动禁用 IPv6 DNS 解析
AI-assisted analysis of docmirror/dev-sidecar@7710cd56cc (2026-08-31).
Data as JSON: /api/errors/57991e635b983933.
Report an issue: GitHub.