Billionmail/BillionMail · error
fail2ban value can only be y/n or 1/0
Error message
fail2ban value can only be y/n or 1/0
What it means
The FAIL2BAN_INIT/fail2ban key is a boolean-style toggle and validateConfigValue only accepts the literal strings y, n, 1 or 0. Any other value (true/false, yes/no, on/off) is rejected because the value is written directly into fail2ban/service configuration that expects this restricted alphabet.
Source
Thrown at core/internal/controller/settings/settings.go:234
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")
}
}
// General character check: not allowed dangerous characters
if public.ContainsDangerousChars(value) {
return fmt.Errorf("configuration value contains illegal characters")
}
return nil
}
View on GitHub (pinned to fc36c76c05)
Solutions
- Send exactly one of: 'y', 'n', '1' or '0'
- Map booleans before the call: true→'1', false→'0'
- Normalize case to lowercase ('Y'→'y') if your source data is uppercase
- Verify the stored value after saving by reading the config back
Example fix
// before FAIL2BAN_INIT = true // after FAIL2BAN_INIT = 1
Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = new Set(['y','n','1','0']);
if (!ALLOWED.has(flag)) throw new Error('fail2ban value can only be y/n or 1/0'); Type guard
function isFail2banFlag(v: string): v is 'y'|'n'|'1'|'0' {
return v === 'y' || v === 'n' || v === '1' || v === '0';
} Try / catch
try {
await api.setSystemConfigKey('FAIL2BAN_INIT', flag);
} catch (e) {
if (String(e.message).includes('fail2ban')) {
notify('Use exactly y, n, 1 or 0 (lowercase)');
} else throw e;
} Prevention
- Map booleans: true→'1', false→'0' before the API call
- Lowercase the value before sending
- Use a select/toggle control, not free text
- Reject 'true'/'false'/'yes'/'no' at the form layer
When it happens
Trigger: Calling SetSystemConfig/SetSystemConfigKey with FAIL2BAN_INIT set to 'true', 'false', 'yes', 'no', 'enabled', 'Y'/'N' if the check is case-sensitive, or an empty string.
Common situations: Frontends or scripts send JSON booleans serialized as 'true'/'false', or users type 'yes'/'no' out of habit; case-sensitivity trips values like 'Yes'.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- hostname format is incorrect
- port must be between 1-65535
- IPv4 network format is incorrect, please use CIDR format (e.
- invalid timezone
- retention_days must be a number
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/358035094e7be2ff.
Report an issue: GitHub.