kubernetes/kops · error
failed to read %s: %w
Error message
failed to read %s: %w
What it means
disableSwap reads /etc/fstab with os.ReadFile to strip swap entries; if that read fails (file missing, permission denied, I/O error), it returns this wrapped error with the path and the underlying OS error. It is the OS-level precondition check for removing swap on Linode nodes.
Source
Thrown at nodeup/pkg/model/linode.go:62
// Akamai (Linode) instances ship with swap enabled. Disable it when MemorySwapBehavior is unset,
// since the default kubelet swap mode (NoSwap) requires swap to be off.
if b.NodeupConfig.KubeletConfig.MemorySwapBehavior == "" {
if err := b.disableSwap(c); err != nil {
return fmt.Errorf("error disabling swap: %v", err)
}
}
return nil
}
// disableSwap disables swap at the OS level and removes swap entries from /etc/fstab
func (b *LinodeBuilder) disableSwap(c *fi.NodeupModelBuilderContext) error {
// Read current /etc/fstab
fstabPath := "/etc/fstab"
fstabBytes, err := os.ReadFile(fstabPath)
if err != nil {
return fmt.Errorf("failed to read %s: %w", fstabPath, err)
}
// Filter out swap entries
var filteredLines []string
scanner := bufio.NewScanner(bytes.NewReader(fstabBytes))
for scanner.Scan() {
line := scanner.Text()
// Keep lines that don't contain " swap " or "\tswap\t"
if !strings.Contains(line, " swap ") && !strings.Contains(line, "\tswap\t") {
filteredLines = append(filteredLines, line)
} else {
klog.V(2).Infof("Removing swap entry from fstab: %s", line)
}
}
if err := scanner.Err(); err != nil {
return fmt.Errorf("error reading fstab: %w", err)
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Create a valid /etc/fstab on the image (even an empty or comment-only file) before nodeup runs
- Fix /etc/fstab permissions so nodeup's user can read it (typically root-readable, e.g. 0644)
- Check the wrapped %w error for the exact errno (ENOENT vs EACCES) and act accordingly
- Set kubelet memorySwapBehavior to skip the fstab-rewriting path
Example fix
// before: minimal image without fstab $ ls /etc/fstab ls: cannot access '/etc/fstab': No such file or directory // after $ touch /etc/fstab && chmod 644 /etc/fstab
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat("/etc/fstab")
if err != nil {
return fmt.Errorf("/etc/fstab must exist and be readable before nodeup: %w", err)
}
if info.IsDir() {
return fmt.Errorf("/etc/fstab is a directory")
} Try / catch
fstabBytes, err := os.ReadFile("/etc/fstab")
if err != nil {
if errors.Is(err, os.ErrNotExist) {
klog.Warningf("/etc/fstab absent; creating empty one")
err = os.WriteFile("/etc/fstab", nil, 0644)
}
if err != nil {
return fmt.Errorf("failed to read /etc/fstab: %w", err)
}
} Prevention
- Bake /etc/fstab into all node images
- Avoid hardening tools that chmod /etc/fstab to unreadable modes
- Check the wrapped errno (ENOENT vs EACCES) to choose between creating the file and fixing perms
When it happens
Trigger: os.ReadFile("/etc/fstab") returns an error during nodeup Build on a Linode instance with MemorySwapBehavior unset — e.g. fstab deleted from the image, wrong permissions, or a broken root filesystem.
Common situations: Minimal/custom Linode images that ship without /etc/fstab; security-hardened images with 0600 perms; containers/chroots where fstab was never created; corrupted disks.
Related errors
- error reading fstab: %w
- path: %s already exists but is not a directory
- error disabling swap: %v
- error checking for /run/cilium/cgroupv2: %v
- failed to ensure the directory: %s, error: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/b5c3dda881b3de3a.
Report an issue: GitHub.