cilium/cilium · error

incorrect value for probed IPSec output mask attribute

Error message

incorrect value for probed IPSec output mask attribute

What it means

This is the second validation in ProbeXfrmStateOutputMask: the kernel DID return the OUTPUT_MARK attribute (OutputMark != nil) but its Mask field does not equal linux_defaults.RouteMarkMask (0x600). Cilium requires the exact route mark mask so its IPSec routing (mark-based interface selection) works; a different mask means the kernel probe state was modified or the constant mismatches what the kernel applied.

Source

Thrown at pkg/datapath/linux/ipsec/probe_linux.go:80

	state := initDummyXfrmState()
	err := createDummyXfrmState(state)
	if err != nil {
		return err
	}
	defer func() {
		//nolint:forbidigo
		e = errors.Join(e, netlink.XfrmStateDel(state))
	}()

	var probedState *netlink.XfrmState
	if probedState, err = netlink.XfrmStateGet(state); err != nil {
		return err
	}
	if probedState == nil || probedState.OutputMark == nil {
		return errors.New("IPSec output mark attribute missing from xfrm probe")
	}
	if probedState.OutputMark.Mask != linux_defaults.RouteMarkMask {
		return errors.New("incorrect value for probed IPSec output mask attribute")
	}
	return
}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Flush stale xfrm states on the node: 'ip xfrm state flush' (or 'ip xfrm state delete' for specific entries) and restart the agent so the probe recreates its state
  2. Check for other IPSec software (strongSwan, Libreswan, WireGuard+masks) on the node and remove conflicting configurations
  3. Verify linux_defaults.RouteMarkMask is not overridden by conflicting mark settings in the Cilium config (e.g. other components using the same mark bits)
  4. Reboot the node if xfrm state cannot be safely flushed while in use
Defensive patterns

Strategy: validation

Validate before calling

// Ensure no conflicting xfrm states/marks exist before starting
out, err := exec.Command("ip", "xfrm", "state").Output()
if err == nil && strings.Contains(string(out), "mark") && conflictingOwner(string(out)) {
    return fmt.Errorf("conflicting xfrm state mark detected; flush with 'ip xfrm state flush'")
}

Type guard

func outputMarkMatchesDefault(state *netlink.XfrmState, want uint32) bool {
    return state != nil && state.OutputMark != nil && state.OutputMark.Mask == want
}

Try / catch

if err := ipsec.ProbeXfrmStateOutputMask(); err != nil {
    if strings.Contains(err.Error(), "incorrect value") {
        _ = exec.Command("ip", "xfrm", "state", "flush").Run() // clear stale states, then retry once
        return ipsec.ProbeXfrmStateOutputMask()
    }
    return err
}

Prevention

When it happens

Trigger: ProbeXfrmStateOutputMask fetches a probed xfrm state whose OutputMark.Mask differs from linux_defaults.RouteMarkMask; typically the xfrm state table was polluted by another component (e.g. another IPSec stack such as strongSwan or a prior Cilium run) that owns the probe state key.

Common situations: Conflicting IPSec software installed on the node creating/overwriting xfrm states with the same SPI/mark; leftover xfrm state from a previous Cilium installation; custom linux_defaults mark configuration that no longer matches the kernel default.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/f6f927f396c9c110. Report an issue: GitHub.