{"record":{"id":"8eade8adab375253","repo":"cilium/cilium","slug":"failed-to-write-update-event-to-wal-w","errorCode":null,"errorMessage":"failed to write update event to WAL: %w","messagePattern":"failed to write update event to WAL: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/datapath/linux/route/reconciler/reconciler.go","lineNumber":208,"sourceCode":"\t\treturn nil\n\t}\n\n\tif obj.Device != nil {\n\t\t// Verify that the device still exists.\n\t\t_, _, found := ops.devices.Get(rxn, tables.DeviceByIndex(obj.Device.Index))\n\t\tif !found {\n\t\t\treturn errDeviceNotFound\n\t\t}\n\t}\n\n\t// Write to the WAL first, then update the route in the kernel.\n\t// If we crash after writing to the WAL but before updating the route, no harm done.\n\terr := ops.wal.Write(reconcilerEvent{\n\t\tDeleted: false,\n\t\tKey:     obj.GetOwnerlessKey(),\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to write update event to WAL: %w\", err)\n\t}\n\n\treturn ops.handle.RouteReplace(desiredRouteToNetlinkRoute(obj))\n}\n\nfunc (ops *ops) Delete(_ context.Context, rxn statedb.ReadTxn, _ statedb.Revision, obj *DesiredRoute) error {\n\t// If the route is not selected, we do not need to delete it.\n\tif !obj.selected {\n\t\treturn nil\n\t}\n\n\t// First delete the route from the kernel, then write to the WAL.\n\t// If we crash after deleting the route but before writing to the WAL, we will\n\t// re-try the deletion on restart, which is safe.\n\terr2 := ops.handle.RouteDel(desiredRouteToNetlinkRoute(obj))\n\n\terr := ops.wal.Write(reconcilerEvent{\n\t\tDeleted: true,","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/datapath/linux/route/reconciler/reconciler.go#L190-L226","documentation":"Update in the route reconciler persists an update event to a write-ahead log (WAL) before replacing the route via netlink, so a crash between WAL write and route update is recoverable. If wal.Write fails, the update is aborted with this wrapped error.","triggerScenarios":"ops.wal.Write returns an error during DesiredRoute upsert — typically WAL file open/write failure (disk full, permission denied, directory missing).","commonSituations":"Full or read-only filesystem hosting the WAL; incorrect state directory permissions; WAL file corrupted or locked by another process.","solutions":["Check disk space and filesystem writability for the WAL directory","Fix permissions on the state/WAL directory","Inspect the wrapped cause for the exact OS error","Move the state directory to a healthy volume and restart"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// WAL dir writable?\nif err := os.MkdirAll(stateDir, 0o750); err != nil { return err }\nprobe := filepath.Join(stateDir, \".wal-probe\")\nif err := os.WriteFile(probe, nil, 0o600); err != nil { return fmt.Errorf(\"state dir not writable: %w\", err) }\nos.Remove(probe)","typeGuard":"var pathErr *os.PathError\nif errors.As(err, &pathErr) { /* inspect pathErr.Err: ENOSPC, EACCES, EROFS */ }","tryCatchPattern":"if err := mgr.Update(ctx, txn, rev, route); err != nil {\n    if strings.Contains(err.Error(), \"failed to write update event to WAL\") { /* check disk/permissions on state dir */ }\n    return err\n}","preventionTips":["Monitor disk space on the volume holding the WAL/state dir","Use a persistent, writable volume for agent state","Fix state directory ownership/permissions at deploy time"],"tags":["wal","routing","reconciler","persistence"],"backgroundTag":"wal-write-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}