{"record":{"id":"74da454047103dab","repo":"cloudflare/cloudflared","slug":"allowed-mail-rule-q-is-not-a-valid-email-address","errorCode":null,"errorMessage":"allowed mail rule %q is not a valid email address","messagePattern":"allowed mail rule %q is not a valid email address","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"connection/quick_tunnel_auth_validation.go","lineNumber":34,"sourceCode":"\t\tentry := normalizeQuickTunnelEmail(rawEntry)\n\t\tdomain, isWildcard := strings.CutPrefix(entry, \"*@\")\n\n\t\tswitch {\n\t\tcase entry == \"\":\n\t\t\treturn nil, nil, fmt.Errorf(\"allowed mail rule %d is empty\", i+1)\n\n\t\tcase isWildcard:\n\t\t\tif !isValidQuickTunnelEmailDomain(domain) {\n\t\t\t\treturn nil, nil, fmt.Errorf(\n\t\t\t\t\t\"allowed mail rule %q has an invalid wildcard domain\",\n\t\t\t\t\trawEntry,\n\t\t\t\t)\n\t\t\t}\n\t\t\twildcardDomains[domain] = struct{}{}\n\n\t\tdefault:\n\t\t\tif !isValidQuickTunnelEmail(entry) {\n\t\t\t\treturn nil, nil, fmt.Errorf(\n\t\t\t\t\t\"allowed mail rule %q is not a valid email address\",\n\t\t\t\t\trawEntry,\n\t\t\t\t)\n\t\t\t}\n\t\t\temails[entry] = struct{}{}\n\t\t}\n\t}\n\n\treturn emails, wildcardDomains, nil\n}\n\nfunc isValidQuickTunnelEmail(email string) bool {\n\taddress, err := mail.ParseAddress(email)\n\t// ParseAddress accepts mailbox forms such as John Smith <jsmith@example.com>,\n\t// so require the input to be a bare email address.\n\tif err != nil || address.Address != email {\n\t\treturn false\n\t}","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/connection/quick_tunnel_auth_validation.go#L16-L52","documentation":"Non-wildcard entries in the allowed-mail list must be syntactically valid email addresses per isValidQuickTunnelEmail. Invalid entries (missing @, invalid local part, bad domain) produce \"allowed mail rule %q is not a valid email address\" quoting the raw entry, preventing unmatchable rules from being accepted into the allowlist.","triggerScenarios":"An allowed mail rule without the \"*@\" prefix fails isValidQuickTunnelEmail — e.g. \"alice\", \"alice@\", \"@example.com\", or \"alice@@example.com\".","commonSituations":"Users entering usernames instead of full email addresses in config; typos like double @; config values where the domain was accidentally stripped.","solutions":["Correct the entry to a complete valid address like \"alice@example.com\"","Verify each comma-separated entry has exactly one '@' with valid local part and domain","If you meant a domain-wide rule, use the wildcard form \"*@example.com\" instead","Validate the list locally (e.g. with a mail regex) before deploying the config"],"exampleFix":"// before\nallowedMail: \"alice\"\n// after\nallowedMail: \"alice@example.com\"","handlingStrategy":"validation","validationCode":"func validEmailRule(entry string) bool {\n\tif strings.HasPrefix(entry, \"*@\") { return true }\n\tat := strings.Count(entry, \"@\")\n\treturn at == 1 && strings.Index(entry, \"@\") > 0 &&\n\t\tstrings.Index(entry, \"@\") < len(entry)-1\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enter complete email addresses, not usernames","Check for double '@' characters in pasted values","Use domain wildcards (\"*@domain\") for domain-wide allowlists instead of malformed emails"],"tags":["go","config","validation","email"],"backgroundTag":"invalid-argument-value","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}