Billionmail/BillionMail · error
port must be between 1-65535
Error message
port must be between 1-65535
What it means
validateConfigValue parses port-type config keys (SMTP_PORT, IMAP_PORT, HTTP_PORT, etc., and their lowercase aliases) with public.ParseInt and requires the result to be in 1-65535. Ports outside that range cannot be bound by the mail services, so the value is rejected before being saved.
Source
Thrown at core/internal/controller/settings/settings.go:216
}
case "ADMIN_PASSWORD", "admin_password":
if len(value) < 4 {
return fmt.Errorf("password length must be at least 4 characters")
}
case "BILLIONMAIL_HOSTNAME", "billionmail_hostname":
// Hostname: allowed letters, numbers, dots, hyphens
if !public.IsValidHostname(value) {
return fmt.Errorf("hostname format is incorrect")
}
case "SMTP_PORT", "SMTPS_PORT", "SUBMISSION_PORT", "IMAP_PORT", "IMAPS_PORT", "POP_PORT", "POPS_PORT", "HTTP_PORT", "HTTPS_PORT", "REDIS_PORT",
"smtp", "smtps", "submission", "imap", "imaps", "pop", "pops", "http", "https", "redis_port":
// Port: 1-65535
port := public.ParseInt(value)
if port < 1 || port > 65535 {
return fmt.Errorf("port must be between 1-65535")
}
case "IPV4_NETWORK", "ipv4_network":
// IPv4 network: CIDR format
if !public.IsValidCIDR(value) {
return fmt.Errorf("IPv4 network format is incorrect, please use CIDR format (e.g. 192.168.1.0/24)")
}
case "TZ", "timezone":
// Timezone: check if it is a valid timezone
if !public.IsValidTimezone(value) {
return fmt.Errorf("invalid timezone")
}
case "FAIL2BAN_INIT", "fail2ban":
// fail2ban: only allowed y/n or 1/0
if value != "y" && value != "n" && value != "1" && value != "0" {
return fmt.Errorf("fail2ban value can only be y/n or 1/0")View on GitHub (pinned to fc36c76c05)
Solutions
- Set the port to an integer between 1 and 65535 (e.g. 25, 465, 587, 993)
- Check for accidental concatenation of the port with other text before sending
- Ensure the value is a plain decimal string with no units or spaces
- If the service should be disabled, use the service's enable/disable flag instead of port 0
Example fix
// before SMTP_PORT = 0 // after SMTP_PORT = 25
Defensive patterns
Strategy: validation
Validate before calling
const p = Number(port);
if (!Number.isInteger(p) || p < 1 || p > 65535) throw new Error('port must be between 1-65535'); Type guard
function isValidPort(v: unknown): v is number {
return typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 65535;
} Try / catch
try {
await api.setSystemConfigKey('SMTP_PORT', String(port));
} catch (e) {
if (String(e.message).includes('port must be between')) {
notify('Enter a TCP port from 1 to 65535');
} else throw e;
} Prevention
- Always send ports as plain decimal strings without units
- Never use 0 to 'disable' a service — use its toggle flag
- Validate with Number.isInteger and range check before submit
- Watch for string concatenation bugs building the port value
When it happens
Trigger: Setting any port key (e.g. SMTP_PORT) to 0, a negative number, a number above 65535, or a non-numeric string that ParseInt maps to an out-of-range value.
Common situations: Copy-paste errors including the plus sign or service name ('SMTP 25'), typos like 655360, empty or blank strings, and attempts to disable a service by setting its port to 0.
Related errors
- hostname format is incorrect
- IPv4 network format is incorrect, please use CIDR format (e.
- invalid timezone
- fail2ban value can only be y/n or 1/0
- retention_days must be a number
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/f1da3ae7d1ea76b5.
Report an issue: GitHub.