{"record":{"id":"b5c3dda881b3de3a","repo":"kubernetes/kops","slug":"failed-to-read-s-w","errorCode":null,"errorMessage":"failed to read %s: %w","messagePattern":"failed to read (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nodeup/pkg/model/linode.go","lineNumber":62,"sourceCode":"\n\t// Akamai (Linode) instances ship with swap enabled. Disable it when MemorySwapBehavior is unset,\n\t// since the default kubelet swap mode (NoSwap) requires swap to be off.\n\tif b.NodeupConfig.KubeletConfig.MemorySwapBehavior == \"\" {\n\t\tif err := b.disableSwap(c); err != nil {\n\t\t\treturn fmt.Errorf(\"error disabling swap: %v\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// disableSwap disables swap at the OS level and removes swap entries from /etc/fstab\nfunc (b *LinodeBuilder) disableSwap(c *fi.NodeupModelBuilderContext) error {\n\t// Read current /etc/fstab\n\tfstabPath := \"/etc/fstab\"\n\tfstabBytes, err := os.ReadFile(fstabPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read %s: %w\", fstabPath, err)\n\t}\n\n\t// Filter out swap entries\n\tvar filteredLines []string\n\tscanner := bufio.NewScanner(bytes.NewReader(fstabBytes))\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\t// Keep lines that don't contain \" swap \" or \"\\tswap\\t\"\n\t\tif !strings.Contains(line, \" swap \") && !strings.Contains(line, \"\\tswap\\t\") {\n\t\t\tfilteredLines = append(filteredLines, line)\n\t\t} else {\n\t\t\tklog.V(2).Infof(\"Removing swap entry from fstab: %s\", line)\n\t\t}\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\treturn fmt.Errorf(\"error reading fstab: %w\", err)\n\t}\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/nodeup/pkg/model/linode.go#L44-L80","documentation":"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.","triggerScenarios":"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.","commonSituations":"Minimal/custom Linode images that ship without /etc/fstab; security-hardened images with 0600 perms; containers/chroots where fstab was never created; corrupted disks.","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"],"exampleFix":"// before: minimal image without fstab\n$ ls /etc/fstab\nls: cannot access '/etc/fstab': No such file or directory\n// after\n$ touch /etc/fstab && chmod 644 /etc/fstab","handlingStrategy":"validation","validationCode":"info, err := os.Stat(\"/etc/fstab\")\nif err != nil {\n    return fmt.Errorf(\"/etc/fstab must exist and be readable before nodeup: %w\", err)\n}\nif info.IsDir() {\n    return fmt.Errorf(\"/etc/fstab is a directory\")\n}","typeGuard":null,"tryCatchPattern":"fstabBytes, err := os.ReadFile(\"/etc/fstab\")\nif err != nil {\n    if errors.Is(err, os.ErrNotExist) {\n        klog.Warningf(\"/etc/fstab absent; creating empty one\")\n        err = os.WriteFile(\"/etc/fstab\", nil, 0644)\n    }\n    if err != nil {\n        return fmt.Errorf(\"failed to read /etc/fstab: %w\", err)\n    }\n}","preventionTips":["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"],"tags":["nodeup","linode","fstab","filesystem"],"backgroundTag":"fstab-read-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}