Billionmail/BillionMail · error

IPv4 network format is incorrect, please use CIDR format (e.

Error message

IPv4 network format is incorrect, please use CIDR format (e.g. 192.168.1.0/24)

What it means

validateConfigValue validates the IPV4_NETWORK key with public.IsValidCIDR and rejects values that are not valid IPv4 CIDR notation. This network is written into Docker/mail-service network configuration, so a malformed value would break container networking. An example is embedded in the message.

Source

Thrown at core/internal/controller/settings/settings.go:222

	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")
		}
	case "RETENTION_DAYS", "retention_days":
		// retention_days: must be a number
		if _, err := strconv.Atoi(value); err != nil {
			return fmt.Errorf("retention_days must be a number")
		}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Use CIDR format with network address and prefix, e.g. 192.168.1.0/24
  2. Convert a netmask to a prefix length (255.255.255.0 → /24)
  3. Validate with a CIDR parser (Go net.ParseCIDR) before calling the API
  4. Match the existing Docker network subnet if one is already deployed

Example fix

// before
IPV4_NETWORK = 192.168.1.0
// after
IPV4_NETWORK = 192.168.1.0/24
Defensive patterns

Strategy: validation

Validate before calling

function isValidCIDR(v: string): boolean {
  const m = v.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$/);
  if (!m) return false;
  const ok = [1,2,3,4].every(i => +m[i] >= 0 && +m[i] <= 255);
  return ok && +m[5] <= 32;
}
if (!isValidCIDR(network)) throw new Error('use CIDR, e.g. 192.168.1.0/24');

Type guard

function isCIDR(v: string): boolean {
  return /^\d{1,3}(\.\d{1,3}){3}\/(\d|[12]\d|3[0-2])$/.test(v);
}

Try / catch

try {
  await api.setSystemConfigKey('IPV4_NETWORK', network);
} catch (e) {
  if (String(e.message).includes('CIDR')) {
    notify('IPv4 network must be in CIDR format, e.g. 192.168.1.0/24');
  } else throw e;
}

Prevention

When it happens

Trigger: Setting IPV4_NETWORK to a bare IP (192.168.1.0), an IPv6 value, a netmask form (255.255.255.0), a range with a hyphen, or an incorrect prefix length (192.168.1.0/33).

Common situations: Users confuse netmask with CIDR prefix, omit the /prefix, or paste the Docker subnet with extra whitespace or a gateway address instead of the network address.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/155dbc17e3d2baad. Report an issue: GitHub.