{"record":{"id":"99b20a971c62ed51","repo":"walkor/workerman","slug":"invalid-protocol-scheme-scheme-99b20a","errorCode":null,"errorMessage":"Invalid protocol scheme '$scheme'","messagePattern":"Invalid protocol scheme '\\$scheme'","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Connection/AsyncUdpConnection.php","lineNumber":85,"sourceCode":"     * @var array\n     */\n    protected array $contextOption = [];\n\n    /**\n     * Construct.\n     *\n     * @param string $remoteAddress\n     * @throws Throwable\n     */\n    public function __construct($remoteAddress, $contextOption = [])\n    {\n        // Get the application layer communication protocol and listening address.\n        [$scheme, $address] = explode(':', $remoteAddress, 2);\n        // Check application layer protocol class.\n        if ($scheme !== 'udp') {\n            // Validate scheme contains only safe characters for class name resolution.\n            if (!preg_match('/^[a-zA-Z][a-zA-Z0-9]*$/', $scheme)) {\n                throw new RuntimeException(\"Invalid protocol scheme '$scheme'\");\n            }\n            $scheme = ucfirst($scheme);\n            $this->protocol = '\\\\Protocols\\\\' . $scheme;\n            if (!class_exists($this->protocol)) {\n                $this->protocol = \"\\\\Workerman\\\\Protocols\\\\$scheme\";\n                if (!class_exists($this->protocol)) {\n                    throw new RuntimeException(\"class \\\\Protocols\\\\$scheme not exist\");\n                }\n            }\n        }\n\n        $this->remoteAddress = substr($address, 2);\n        $this->contextOption = $contextOption;\n    }\n\n    /**\n     * For udp package.\n     *","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/walkor/workerman/blob/1391112a61d23020e11e7b89f17050f6cfaea431/src/Connection/AsyncUdpConnection.php#L67-L103","documentation":"AsyncUdpConnection splits the address on the first ':' and expects the scheme 'udp' for a plain UDP transport. Any other scheme is treated as an application-layer protocol class name, and before building '\\Protocols\\<Scheme>' Workerman validates it against /^[a-zA-Z][a-zA-Z0-9]*$/. A scheme containing hyphens, dots, leading digits or symbols throws immediately.","triggerScenarios":"new AsyncUdpConnection('my-proto://1.2.3.4:53') (hyphen), scheme starting with a digit like '2dns://host', an address with junk before ':' such as '//udp://host:53', or an empty address string.","commonSituations":"Custom UDP-based protocol named with dashes instead of alphanumeric PascalCase; address assembled from config where the scheme variable contains whitespace or a typo; copy-pasting a TCP address scheme into a UDP connection.","solutions":["Use the exact scheme 'udp://' for plain UDP, e.g. new AsyncUdpConnection('udp://1.2.3.4:53')","For a custom protocol, rename the scheme to /^[a-zA-Z][a-zA-Z0-9]*$/ (e.g. 'mydns://host:53') and provide Protocols\\Mydns","Trim and validate the scheme portion of the address string before constructing the connection"],"exampleFix":"// before\n$conn = new AsyncUdpConnection('my-dns://8.8.8.8:53'); // throws Invalid protocol scheme 'my-dns'\n\n// after\n$conn = new AsyncUdpConnection('mydns://8.8.8.8:53'); // uses Protocols\\Mydns","handlingStrategy":"validation","validationCode":"$scheme = strtolower(explode(':', (string)$address, 2)[0]);\nif (!preg_match('/^[a-zA-Z][a-zA-Z0-9]*$/', $scheme)) {\n    throw new InvalidArgumentException(\"Bad UDP protocol scheme: '$scheme'\");\n}\n$conn = new AsyncUdpConnection($address);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default to the literal 'udp://' scheme unless a custom wire protocol is really needed","Keep custom UDP protocol names alphanumeric and letter-first"],"tags":["php","workerman","udp","protocol","scheme-validation"],"backgroundTag":"invalid-url-scheme","analyzedSha":"1391112a61d23020e11e7b89f17050f6cfaea431","analyzedAt":"2026-08-21T02:05:46.744Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}