cilium/cilium · error

could not write to the sysctl file %s: %w

Error message

could not write to the sysctl file %s: %w

What it means

directSysctl.Write opened the /proc/sys file successfully, but io.WriteString failed, so the kernel's write error (typically EPERM/EACCES for insufficient privilege, or EINVAL for an invalid value) is wrapped as 'could not write to the sysctl file'. Reached via Write, WriteInt, Enable/Disable, or ApplySettings.

Source

Thrown at pkg/datapath/linux/sysctl/sysctl.go:217

	// Check if the value is already set to the desired value.
	val, err := ay.Read(name)
	if err != nil {
		return fmt.Errorf("could not read the sysctl file %s: %w", path, err)
	}
	// If the value is already set, return.
	if strings.TrimRight(string(val), "\n") == value {
		return nil
	}

	f, err := ay.fs.OpenFile(path, os.O_RDWR, 0644)
	if err != nil {
		return fmt.Errorf("could not open the sysctl file %s: %w", path, err)
	}
	defer f.Close()

	if _, err := io.WriteString(f, value); err != nil {
		return fmt.Errorf("could not write to the sysctl file %s: %w",
			path, err)
	}
	return nil
}

func (ay *directSysctl) WriteInt(name []string, val int64) error {
	return ay.Write(name, strconv.FormatInt(val, 10))
}

func (ay *directSysctl) ApplySettings(sysSettings []tables.Sysctl) error {
	for _, s := range sysSettings {
		if err := ay.Write(s.Name, s.Val); err != nil {
			return err
		}
	}

	return nil
}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Grant capabilities/privileged mode so the kernel accepts the write (securityContext with needed caps, --privileged, or Kubernetes allowedUnsafeSysctls).
  2. Reproduce manually with `echo <value> > <path>` and read the errno.
  3. Validate the value against kernel expectations for that sysctl (0/1, numeric range).
  4. If ApplySettings fails, identify which entries' sysctls are blocked and pre-flight them at startup.

Example fix

// before (k8s pod)
securityContext: {}
// after (k8s pod)
securityContext:
  privileged: true
# or pod-level:
# spec:
#   securityContext:
#     sysctls:
#       - name: net.ipv4.ip_forward
#         value: "1"
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the kernel accepts the value by test-writing before ApplySettings
if err := writeSysctlProbe("/proc/sys/net/ipv4/ip_forward", "1"); err != nil {
	return fmt.Errorf("kernel rejects sysctl write: %w", err)
}

Try / catch

err := sysctl.WriteInt(name, 1)
if err != nil {
	var perr *os.PathError
	if errors.As(err, &perr) && errors.Is(perr.Err, syscall.EPERM) {
		// missing capability: surface actionable message
	}
	return err
}

Prevention

When it happens

Trigger: Writing a sysctl the kernel refuses: process lacks CAP_NET_ADMIN for namespaced sysctls, the sysctl is set read-only by the container runtime, or the value is invalid for that parameter.

Common situations: Setting net.ipv4.ip_forward or bridge netfilter sysctls inside an unprivileged container; Kubernetes pods without the right securityContext or with disallowed unsafe sysctls; writing out-of-range values.

Related errors


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