XTLS/Xray-core · warning · errors.Error

Log Mask: ipv4 mask must be divisible by 8 and between 0-32

Error message

Log Mask: ipv4 mask must be divisible by 8 and between 0-32

What it means

ParseMaskAddress validates the IPv4 mask parsed from the log mask address setting: after resolving named presets (half/quarter/full) or numeric 'm4+m6' forms, m4 must be in 0..32 and divisible by 8. Otherwise the default safe mask (32/128, i.e. fully masked) is returned together with this error.

Source

Thrown at app/log/log.go:197

			if len(parts) >= 1 && parts[0] != "" {
				i, err := strconv.Atoi(strings.TrimPrefix(parts[0], "/"))
				if err != nil {
					return 32, 128, err
				}
				m4 = i
			}
			if len(parts) >= 2 && parts[1] != "" {
				i, err := strconv.Atoi(strings.TrimPrefix(parts[1], "/"))
				if err != nil {
					return 32, 128, err
				}
				m6 = i
			}
		}
	}

	if m4%8 != 0 || m4 > 32 || m4 < 0 {
		return 32, 128, errors.New("Log Mask: ipv4 mask must be divisible by 8 and between 0-32")
	}

	return m4, m6, nil
}

// MaskedMsgWrapper is to wrap the string() method to mask IP addresses in the log.
type MaskedMsgWrapper struct {
	log.Message
	Mask4 int
	Mask6 int
}

var (
	ipv4Regex = regexp.MustCompile(`(\d{1,3}\.){3}\d{1,3}`)
	ipv6Regex = regexp.MustCompile(`(?:[\da-fA-F]{0,4}:[\da-fA-F]{0,4}){2,7}`)
)

func (m *MaskedMsgWrapper) String() string {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Use one of the named presets: 'half' (16/32), 'quarter' (8/16), or 'full' (0/0)
  2. If numeric, ensure the IPv4 part is 0, 8, 16, 24, or 32, e.g. '24+56'
  3. Re-check the value against the error constraints after any config template upgrade

Example fix

// before
"log": { "maskAddress": "20+64" } // 20 not divisible by 8
// after
"log": { "maskAddress": "24+64" } // valid: 24 % 8 == 0, 24 <= 32
Defensive patterns

Strategy: validation

Validate before calling

// Validate a mask address before applying config (mirror of ParseMaskAddress):
func validMask(m4 int) bool { return m4 >= 0 && m4 <= 32 && m4%8 == 0 }
// or simply call the real parser:
if _, _, err := log.ParseMaskAddress(cfgValue); err != nil {
    return fmt.Errorf("invalid maskAddress %q: %w", cfgValue, err)
}

Type guard

func isValidIPv4Mask(m4 int) bool {
    return m4 >= 0 && m4 <= 32 && m4%8 == 0
}

Prevention

When it happens

Trigger: Setting log maskAddress to a numeric form whose IPv4 part fails validation: '33+128', '12', '-8', '9/24' style values — anything not a multiple of 8 within 0-32. Note only m4 is range-checked here; m6 is unconstrained by this specific error.

Common situations: Copy-pasting CIDR notation like '/24' with unexpected prefixes; assuming any 0-32 value works when only octet-aligned masks (0,8,16,24,32) are accepted; typos in the m4+m6 syntax.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/2722d33eba7eace8. Report an issue: GitHub.