{"record":{"id":"f721e1644ea21a43","repo":"louislam/uptime-kuma","slug":"unsupported-proxy-protocol-provided-proxy-proto","errorCode":null,"errorMessage":"Unsupported proxy protocol provided. ${proxy.protocol}","messagePattern":"Unsupported proxy protocol provided\\. (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/proxy.js","lineNumber":151,"sourceCode":"            case \"socks5\":\n            case \"socks5h\":\n            case \"socks4\":\n                // eslint-disable-next-line no-case-declarations\n                const SocksCookieProxyAgent = createCookieAgent(SocksProxyAgent);\n                agent = new SocksCookieProxyAgent(proxyUrl.toString(), {\n                    ...httpAgentOptions,\n                    ...httpsAgentOptions,\n                    tls: {\n                        rejectUnauthorized: httpsAgentOptions.rejectUnauthorized,\n                    },\n                });\n\n                httpAgent = agent;\n                httpsAgent = agent;\n                break;\n\n            default:\n                throw new Error(`Unsupported proxy protocol provided. ${proxy.protocol}`);\n        }\n\n        return {\n            httpAgent,\n            httpsAgent,\n        };\n    }\n\n    /**\n     * Reload proxy settings for current monitors\n     * @returns {Promise<void>}\n     */\n    static async reloadProxy() {\n        const server = UptimeKumaServer.getInstance();\n\n        let updatedList = await R.getAssoc(\"SELECT id, proxy_id FROM monitor\");\n\n        for (let monitorID in server.monitorList) {","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/proxy.js#L133-L169","documentation":"Thrown by Proxy.createAgents in the default branch of the protocol switch. This is a defensive guard reached only if proxy.protocol is not http/https/socks/socks5/socks5h/socks4 at agent-construction time. Because Proxy.save already validates protocol against SUPPORTED_PROXY_PROTOCOLS (and the switch covers all of them), reaching this branch implies the bean's protocol was mutated after saving, loaded from a legacy/partial DB row, or created by code that bypassed save().","triggerScenarios":"A monitor loads a proxy bean whose protocol field is null/empty/unknown (legacy DB row from before validation existed), an external process inserted a proxy row directly into the DB with an invalid protocol, or upstream save() validation was bypassed.","commonSituations":"Old DB row predating the SUPPORTED_PROXY_PROTOCOLS check, direct SQL insert with a bad protocol, or schema drift after a partial migration.","solutions":["Inspect the proxy row in the DB (SELECT id, protocol FROM proxy) and correct any non-canonical value to one of http/https/socks/socks5/socks5h/socks4.","If the protocol is null, re-save the proxy through the UI to run validation and populate the field.","Ensure no external script writes to the proxy table without going through Proxy.save.","As defense-in-depth, call Proxy.save's validation before createAgents, or normalize the protocol at agent-build time."],"exampleFix":"// before\nswitch (proxy.protocol) {\n    case \"http\": /*...*/ break;\n    case \"socks\": /*...*/ break;\n    default:\n        throw new Error(`Unsupported proxy protocol provided. ${proxy.protocol}`);\n}\n// after (fail fast with the supported list so the operator knows what to fix)\nconst protocol = (proxy.protocol || \"\").toLowerCase();\nif (!Proxy.SUPPORTED_PROXY_PROTOCOLS.includes(protocol)) {\n    throw new Error(`Unsupported proxy protocol \"${protocol}\". Supported: ${Proxy.SUPPORTED_PROXY_PROTOCOLS.join(\", \")}`);\n}","handlingStrategy":"validation","validationCode":"// Validate protocol immediately before building agents\nconst protocol = (proxy.protocol || \"\").toLowerCase();\nif (!Proxy.SUPPORTED_PROXY_PROTOCOLS.includes(protocol)) {\n    throw new Error(`Unsupported proxy protocol \"${protocol}\". Supported: ${Proxy.SUPPORTED_PROXY_PROTOCOLS.join(\", \")}`);\n}","typeGuard":"/** True when the bean protocol is one createAgents can handle. */\nfunction isAgentCompatibleProtocol(protocol) {\n    return typeof protocol === \"string\" &&\n        [\"http\",\"https\",\"socks\",\"socks5\",\"socks5h\",\"socks4\"].includes(protocol.toLowerCase());\n}","tryCatchPattern":"if (!isAgentCompatibleProtocol(proxy.protocol)) {\n    throw new Error(`Unsupported proxy protocol provided. ${proxy.protocol}`);\n}\n// ...switch (proxy.protocol) { ... }","preventionTips":["Never write proxy rows via raw SQL — go through Proxy.save so validation runs.","Run a DB sweep for legacy/NULL protocols after upgrades.","Re-save proxies through the UI to repopulate validated fields."],"tags":["proxy","defensive","config","db-integrity","enum"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}