{"record":{"id":"2f2c250d807df700","repo":"louislam/uptime-kuma","slug":"nonexistant-or-inaccessible-due-to-acls-line","errorCode":null,"errorMessage":"Nonexistant or inaccessible due to ACLs: \"${line}\"","messagePattern":"Nonexistant or inaccessible due to ACLs: \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/monitor-types/tailscale-ping.js","lineNumber":65,"sourceCode":"     * @param {object} heartbeat The heartbeat object to update.\n     * @returns {void}\n     * @throws Will throw an eror if the output contains any unexpected string.\n     */\n    parseTailscaleOutput(tailscaleOutput, heartbeat) {\n        let lines = tailscaleOutput.split(\"\\n\");\n\n        for (let line of lines) {\n            if (line.includes(\"pong from\")) {\n                heartbeat.status = UP;\n                let time = line.split(\" in \")[1].split(\" \")[0];\n                heartbeat.ping = parseInt(time);\n                heartbeat.msg = \"OK\";\n                break;\n            } else if (line.includes(\"timed out\")) {\n                throw new Error(`Ping timed out: \"${line}\"`);\n                // Immediately throws upon \"timed out\" message, the server is expected to re-call the check function\n            } else if (line.includes(\"no matching peer\")) {\n                throw new Error(`Nonexistant or inaccessible due to ACLs: \"${line}\"`);\n            } else if (line.includes(\"is local Tailscale IP\")) {\n                throw new Error(`Tailscale only works if used on other machines: \"${line}\"`);\n            } else if (line !== \"\") {\n                throw new Error(`Unexpected output: \"${line}\"`);\n            }\n        }\n    }\n}\n\nmodule.exports = {\n    TailscalePing,\n};\n","sourceCodeStart":47,"sourceCodeEnd":78,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/monitor-types/tailscale-ping.js#L47-L78","documentation":"Thrown by parseTailscaleOutput() when an output line contains 'no matching peer'. Tailscale emits this when the target name/IP does not correspond to any node in the current tailnet, or when ACL rules prevent the source from reaching that peer.","triggerScenarios":"Produced when 'tailscale ping <hostname>' cannot map the target to a known peer — either the name is wrong, the peer left the tailnet, or the tailnet ACLs deny access from this node to the target.","commonSituations":"Typo in the target hostname/IP; target was removed from the tailnet; user's role lacks access to that node per ACL policy; tailnet key rotation removed the peer; pinging a name from a different tailnet than intended.","solutions":["Run 'tailscale status' and confirm the target appears in the peer list with the name/IP used in the monitor.","Verify ACL policy grants the source node access to the target.","Correct the hostname/IP in the monitor to match a listed peer.","If the peer was removed, re-invite/rejoin it to the tailnet."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function isNoMatchingPeer(line) { return typeof line === \"string\" && line.includes(\"no matching peer\"); }","typeGuard":"function isKnownPeer(peerName, status) { return status.some(p => p.name === peerName || p.ip === peerName); }","tryCatchPattern":"if (isNoMatchingPeer(line)) { heartbeat.status = DOWN; heartbeat.msg = `Inaccessible due to ACLs: \"${line}\"`; return; }","preventionTips":["Verify the target appears in 'tailscale status'.","Confirm ACL policy grants the source access to the peer.","Avoid typos by copying the peer name/IP from 'tailscale status'."],"tags":["tailscale","acl","peer","vpn"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}