honojs/hono · error · TypeError
Invalid rule: ${rule}
Error message
Invalid rule: ${rule} What it means
This TypeError is thrown by the ip-restriction middleware's CIDR parsing when a rule string's prefix (the part after '/') is not 1-3 digits or exceeds the maximum prefix length for the address family (32 for IPv4, 128 for IPv6). Rules are parsed eagerly when the middleware is created, so bad rules fail fast with 'Invalid rule: <rule>'.
Source
Thrown at src/middleware/ip-restriction/index.ts:43
/**
* ### IPv4 and IPv6
* - `*` match all
*
* ### IPv4
* - `192.168.2.0` static
* - `192.168.2.0/24` CIDR Notation
*
* ### IPv6
* - `::1` static
* - `::1/10` CIDR Notation
*/
type IPRestrictionRuleFunction = (addr: { addr: string; type: AddressType }) => boolean
export type IPRestrictionRule = string | ((addr: { addr: string; type: AddressType }) => boolean)
const IS_CIDR_NOTATION_REGEX = /\/[^/]*$/
const parseCidrPrefix = (rule: string, prefix: string, max: number): number => {
if (!/^[0-9]{1,3}$/.test(prefix)) {
throw new TypeError(`Invalid rule: ${rule}`)
}
const parsedPrefix = parseInt(prefix)
if (parsedPrefix > max) {
throw new TypeError(`Invalid rule: ${rule}`)
}
return parsedPrefix
}
const buildMatcher = (
rules: IPRestrictionRule[]
): ((addr: { addr: string; type: AddressType; isIPv4: boolean }) => boolean) => {
const functionRules: IPRestrictionRuleFunction[] = []
const staticRules: Set<string> = new Set()
const staticIPv4Rules: Set<bigint> = new Set()
const staticIPv6Rules: Set<bigint> = new Set()
const cidrRules: [boolean, bigint, bigint][] = []
const registerStaticRule = (rule: string): void => {
const type = distinctRemoteAddr(rule)
if (type === undefined) {View on GitHub (pinned to e2740d5a1b)
Solutions
- Correct the rule to valid CIDR: digits only after the slash, within 0-32 (IPv4) or 0-128 (IPv6)
- If rules come from config/env, validate them at startup (regex + range check) before creating the middleware
- Use the function form of a rule — (addr) => boolean — for non-CIDR logic instead of malformed strings
- Test rule lists in CI so a typo fails the build, not deployment
Example fix
// before const restriction = ipRestriction(['10.0.0.0/8x', '192.168.1.0/24']) // after const restriction = ipRestriction(['10.0.0.0/8', '192.168.1.0/24'])
Defensive patterns
Strategy: validation
Validate before calling
const isValidCidrRule = (rule: string): boolean => {
const m = rule.match(/^(\d{1,3}(?:\.\d{1,3}){3}|[0-9a-fA-F:]+)\/(\d{1,3})$/)
if (!m) return false
const max = rule.includes(':') ? 128 : 32
return Number(m[2]) <= max
}
const rules = (process.env.ALLOWED_CIDRS ?? '').split(',').map((s) => s.trim()).filter(Boolean)
if (!rules.every(isValidCidrRule)) throw new Error('Invalid CIDR in ALLOWED_CIDRS')
const mw = ipRestriction(rules) Type guard
const isCidrRule = (r: string): boolean => {
const idx = r.lastIndexOf('/')
if (idx === -1) return true // plain IP
const prefix = r.slice(idx + 1)
const max = r.includes(':') ? 128 : 32
return /^[0-9]{1,3}$/.test(prefix) && parseInt(prefix) <= max
} Try / catch
null
Prevention
- Treat allowlists as validated config: parse and check CIDR rules at startup
- Write CIDR prefixes as /N, never as subnet masks
- Add CI validation for env-provided IP rules
- Prefer the function rule form for anything programmatic
When it happens
Trigger: Passing rules like '10.0.0.0/8x' (non-numeric prefix), '10.0.0.0/' or '10.0.0.0/abc' (fails the digits regex), '10.0.0.0/33' (>32 for IPv4), '::1/129' (>128 for IPv6); building rules from user input or env vars without validation; joining rules with extra slashes.
Common situations: Env-configured allowlists with typos, generating CIDR ranges programmatically and emitting an empty or invalid prefix, confusing subnet mask notation (255.255.0.0) with CIDR prefix length (/16), or IPv6 rules written with an embedded '/' mistake.
Related errors
- basic auth middleware requires options for "username and pas
- bearer auth middleware requires options for "token" or "veri
- Middleware vary configuration cannot include "*", as it disa
- JWK auth middleware requires options for either "keys" or "j
- Forbidden
AI-assisted analysis of honojs/hono@e2740d5a1b (2026-08-28).
Data as JSON: /api/errors/2600f0f19787391d.
Report an issue: GitHub.