Need for speed! ποΈ π¨Β Headlamp 0.44.0 extends practical cluster support beyond 30,000 pods. Resource Map remains usable at this scale, Pod lists fetch 1,000 items at a time, Cluster Overview avoids unbounded watch traffic, and Brotli pre-compression reduces typical JavaScript and CSS transfers by 75-80% and server load for compression to 0%. Got dozens of clusters? Headlamp doesn't try to connect to all of them at startup anymore (potentially opening several browser login windows). Four new structured forms cover DaemonSets, CronJobs, Jobs, and ReplicaSets, while ConfigMap binaryData, ServiceAccount permission visibility, Gateway API v1.5.1, and new plugin controls expand day-to-day capabilities. The release includes 99+ bug fixes, including protections against white-screen startup failures when developing Headlamp on Windows, more accurate workload health reporting, stable large-manifest editing on large busy clusters, and actionable cluster connection errors. Accessibility work restores macOS zoom, improves WCAG AA contrast in a few spots, and broadens automated a11y checks. Security and documentation updates add github cosign of release checksums, safer redirects, tested in-cluster kubeconfig examples, and ready-to-use MCP configurations.
These changes were contributed by over 100+ people. Thanks! π
β‘ Performance
| ResourceMap performance improved with iterative BFS, graph simplification, and incremental WebSocket updates β 59% faster initial load and 86% faster updates at 2,000 pods, and clusters with 20,000+ pods are now usable where they previously crashed the browser. | Thanks to @illume. Also thanks to @itpick for reporting the issue. #4991 |
| Cluster overview now polls pod, node, and event data every minute instead of using persistent watch streams, preventing browser OOMs on large clusters. | Thanks to @Aamod007. Also thanks to @lucas-jackson for reporting the issue. #6021 |
| Optimized sidebar rendering to eliminate UI lag and main thread blocking caused by unnecessary DOM nodes and layout thrashing during CSS transitions. | Thanks to @Psykii22. #6233 |
| Frontend and plugin static assets are now precompressed with Brotli and served as .br sidecars β JS/CSS bundles are 75β80% smaller over the wire, WASM assets ~60% smaller, and runtime CPU compression overhead drops to zero. | Thanks to @illume. #6004 |
| Fixed a memory leak where Backstage receiver event listeners accumulated on each remount of the Home component, improving stability during navigation. | Thanks to @Rohith-Saran. #5775 |
| Fixed unbounded memory growth in OIDC login by evicting abandoned state tokens that were never cleaned up when users left the login flow. | Thanks to @ayushmaan-16. #5866 |
| Reduced per-message memory allocations in the WebSocket multiplexer hot path by replacing reflection-based decoding and fmt.Sprintf with typed structs and string concatenation. | Thanks to @Slambot01. #6294 |
Reduced memory allocations in the k8cache hot path by checking error status before marshalling and replacing fmt.Sprintf with string concatenation, improving cache performance. |
Thanks to @Slambot01. #6420 |
| Replaced repeated linear metrics searches with a memoized namespace/name-keyed Map in the Pod List, reducing CPU overhead during metric lookups. | Thanks to @skools-here. #6011 |
| Added pagination to the Pods list with a 1000-item budget and a load-more button, preventing out-of-memory crashes on clusters with tens of thousands of pods. | Thanks to @drewbailey. #5660 |
ResourceMap performance improved with iterative BFS, graph simplification, and incremental WebSocket updates.
20,000+ pods β all operations under 37ms, where previously the browser would crash:
Added pagination to the Pods list with a 1,000-item budget and a load-more button, preventing out-of-memory crashes on clusters with tens of thousands of pods.
π± Mobile
A mobile audit was done, and a number of improvements were made.
| Tables now hide least-important columns first on narrow viewports instead of squashing them, keeping visible data readable at high zoom levels. | Thanks to @skoeva. #6468 |
| Fixed several mobile UI issues including overflow-menu, dialog, terminal, editor, and temporary-sidebar behaviour, making the interface more reliable on small screens. | Thanks to @illume. #5739 |
Tables now hide least-important columns first on narrow viewports instead of squashing them.
Mobile overflow menus and terminal dialogs now use the available screen space more effectively.
β¨ Enhancements (part 1 of 2)
Administrators can now set a custom default node shell image via a --node-shell-image flag and Helm value, useful for airgapped or restricted deployments. |
Thanks to @aryanraj45. #6056 |
| The ServiceAccount detail page now lists all RoleBindings and ClusterRoleBindings that reference the account, making it easy to audit granted permissions. | Thanks to @sudhidutta7694. Also thanks to @jcpunk for reporting the issue. #6040 |
| Added a structured creation form for DaemonSets, letting users create DaemonSet resources through the UI form alongside the existing YAML editor. | Thanks to @vyncent-t. #6514 |
Added a structured CreateCronJobForm for CronJob resources, letting users configure schedule, time zone, concurrency policy, and job template fields through the UI. |
Thanks to @vyncent-t. #6422 |
| Added a structured create form for Job resources with field validation, reusable metadata fields, and a new boolean/checkbox field type. | Thanks to @vyncent-t. #6343 |
In-cluster context name is now automatically derived from the kubeadm-config ConfigMap, removing the need to manually set --in-cluster-context-name. |
Thanks to @Anjali-Chauhan1. Also thanks to @jcpunk for reporting the issue. #6342 |
Added support for the binaryData field in ConfigMap detail and list views, so binary entries are now displayed, editable, and counted alongside data. |
Thanks to @dabico. #6264 |
| Node debugger settings now show the actual default Docker image and namespace as dynamic placeholders, matching backend configuration including custom overrides. | Thanks to @dabico. #6253 |
| Added Arabic, Hebrew, and Russian localizations to the data table component so users of those languages see correctly translated table UI strings. | Thanks to @Priyanshu-rgbb. #6226 |
| YAML syntax errors in EditorDialog now display a red squiggly underline at the exact line and column, making it easier to spot and fix invalid YAML before applying. | Thanks to @Psykii22. #5954 |
Added support for the binaryData field in ConfigMap detail and list views, so binary entries are now displayed, editable, and counted alongside data.
Added a structured creation form for DaemonSets, letting users create DaemonSet resources through the UI form alongside the existing YAML editor.
YAML syntax errors in EditorDialog now display a red squiggly underline at the exact line and column, making it easier to spot and fix invalid YAML before applying.
β¨ Enhancements (part 2 of 2)
| Headlamp now auto-connects only to recently-used clusters on startup, avoiding slow or disruptive credential prompts for users with many clusters in their kubeconfig. | Thanks to @skoeva. #6169 |
| Added a --node-shell-namespace flag and Helm value so admins can configure the namespace used for node shell pods instead of defaulting to 'default'. | Thanks to @aryanraj45. #6072 |
| Added a structured create form for ReplicaSets with Metadata, Spec, and Pod Template sections, so users no longer need to write raw YAML to create one. | Thanks to @vyncent-t. #5995 |
| Added 100 as a rows-per-page option in resource tables, reducing the number of paginations needed when browsing namespaces with more than 50 resources. | Thanks to @ibshafique. #5971 |
| Added a color-coded usage progress bar to the ResourceQuota detail view, making it easy to spot quota pressure at a glance. | Thanks to @beep-boopp. #5875 |
| Added a desktop setting to optionally hide the system tray icon, giving users who prefer no tray presence an easy opt-out. | Thanks to @VlatkoMilisav. #5754 |
| Added a tooltip disclaimer next to Events tables explaining Kubernetes Event retention lifetime, helping users understand why older events may disappear. | Thanks to @dabico. #5531 |
Headlamp now auto-connects only to recently-used clusters on startup, avoiding slow or disruptive credential prompts for users with many clusters in their kubeconfig.
Added a color-coded usage progress bar to the ResourceQuota detail view, making it easy to spot quota pressure at a glance.
Added a structured CreateCronJobForm for CronJob resources, letting users configure schedule, time zone, concurrency policy, and job template fields through the UI.
Added a tooltip disclaimer next to Events tables explaining Kubernetes Event retention lifetime, helping users understand why older events may disappear.
π Bug fixes (part 1 of 11)
| Headlamp desktop now only terminates its own user's headlamp-server processes, preventing one user on a shared machine from killing another user's backend. | Thanks to @Aamod007. Also thanks to @lombardialess for reporting the issue. #6522 |
| Resolved known npm dependency vulnerabilities across all packages by applying npm audit fixes. | Thanks to @yolossn. #6671 |
| Fixed the active tab highlight in NavigationTabs so tabs like Network Policies are correctly selected when hidden sidebar items are filtered out. | Thanks to @Adii-45. #6251 |
| Fixed port forwarding list appearing empty for dynamically added clusters by returning the correct cluster name instead of the internal user-suffixed cache key. | Thanks to @Athang69. Also thanks to @ondrab1 for reporting the issue. #6188 |
| Fixed the Pods overview chart always showing 100% running by correctly reflecting pods in Error, CrashLoopBackOff, Pending, and other non-running states. | Thanks to @xonas1101. #6114 |
| Stale Kubernetes API responses and authorization clientsets are now purged immediately when a kube context is removed, preventing stale data from being served. | Thanks to @Pragati5-DEBUG. #6113 |
StorageClass list no longer shows undefined in the Allow Volume Expansion column β the cell now displays Yes/No or remains empty when the field is absent. |
Thanks to @dabico. #6308 |
Added service.appProtocol support to the Headlamp Helm chart, fixing WebSocket and Gateway API compatibility issues with Kubernetes ingress routing. |
Thanks to @cgiraldo. #6049 |
StorageClass list no longer shows undefined in the Allow Volume Expansion column β the cell now displays Yes/No or remains empty when the field is absent.
π Bug fixes (part 2 of 11)
| API discovery errors and fallbacks are now logged instead of silently swallowed, making it easier to diagnose why legacy discovery paths are being taken. | Thanks to @WasThatRudy. Also thanks to @krsatyamthakur-droid for reporting the issue. #6033 |
Helm chart env values schema now supports valueFrom (secretKeyRef, configMapKeyRef, fieldRef), enabling Kubernetes-native secret and config injection for Headlamp deployments. |
Thanks to @Athang69. Also thanks to @The-Judge for reporting the issue. #6002 |
Fixed cache middleware crashing with 'invalid url format' on non-API cluster paths like /healthz, so proxied apiserver endpoints are handled correctly. |
Thanks to @Nabsku. #5798 |
| Improved hook memoization and lazy initialization in ResourceTable settings, resolving React hook warnings without changing table behavior. | Thanks to @kishore08-07. #5790 |
| Added full support for Kubernetes Gateway API v1.5.1, including BackendTLSPolicy, GRPCRoute, and ReferenceGrant graduating to the Standard channel. | Thanks to @YotamKorah. #5395 |
Fixed a race condition in kubeconfig WriteToFile that caused data corruption or missing files when concurrent calls occurred within the same second. |
Thanks to @KumarADITHYA123. #5309 |
| Metrics unavailability (timeouts, CrashLoopBackOff, etc.) now correctly shows a 'metrics unavailable' state instead of silently displaying 0% CPU and memory usage. | Thanks to @Shreya2005-2005. #5238 |
Guarded against undefined uid and name in search filtering, preventing a crash when resources with incomplete metadata appear in the list. |
Thanks to @krsatyamthakur-droid. #6680 |
| Updated outdated frontend packages across app, headlamp-plugin, pluginctl, eslint-config, and i18n tooling to improve compatibility and security. | Thanks to @illume. #6679 |
| Fixed a failing cluster snapshot test on the main branch introduced by a recent merge. | Thanks to @illume. #6665 |
π Bug fixes (part 3 of 11)
| Images embedded as raw HTML in GitHub release notes now render correctly in the Release Notes dialog instead of being silently dropped. | Thanks to @Pragati5-DEBUG. Also thanks to @skoeva for reporting the issue. #6642 |
| Fixed the desktop e2e suite so all tests pass reliably and no longer corrupt the developer's kubeconfig on each run. | Thanks to @unlikelyzero. #6641 |
| Fixed the DataField editor collapsing to 5px at non-100% browser zoom levels by calculating container height in React instead of via imperative DOM mutations. | Thanks to @bhuvan-somisetty. Also thanks to @hxl9654 for reporting the issue. #6619 |
| Fixed a crash on the Secrets list page caused by corrupt localStorage JSON for the 'Hide Helm Secrets' toggle, replacing the unguarded parse with safe fallback handling. | Thanks to @Aamod007. #6526 |
Fixed a white-screen-on-boot caused by corrupt notifications localStorage JSON being parsed before any error boundary mounted, so the app now loads normally instead of crashing. |
Thanks to @Aamod007. #6524 |
| Enforced minimum Vitest coverage thresholds for the frontend suite so CI automatically catches real regressions in statements, branches, functions, and lines. | Thanks to @rootp1. #6486 |
Images embedded as raw HTML in GitHub release notes now render correctly in the Release Notes dialog instead of being silently dropped.
π Bug fixes (part 4 of 11)
| Added a nil-error guard in the backend handleError helper to prevent a panic when a nil error is accidentally passed by any of its callers. | Thanks to @vtushar06. #6437 |
| Fixed a regression where searching for a namespace name flooded results with every resource in that namespace; the 'Set namespace' shortcut now appears correctly and only once. | Thanks to @Priyanshu-rgbb. #6432 |
Fixed MULTI_HOME_ENABLED always evaluating to true, so setting REACT_APP_MULTI_HOME_ENABLED=false now correctly disables the Multi Home feature. |
Thanks to @ssz2605. #6424 |
| Cluster rename via kubeconfig now returns an explicit error when the target context is missing, preventing silent failures that left state unchanged. | Thanks to @rootp1. #6415 |
Fixed metricTargetValue() in HPA to correctly display 0% for zero averageUtilization values and ensure all metric types are evaluated properly. |
Thanks to @skools-here. #6412 |
Fixed typos in platform and contributing docs and updated Node.js/npm version prerequisites in plugin tutorials to match current package.json requirements. |
Thanks to @Harsh63870. #6408 |
| Reformatted the Desktop App dependency list in the architecture docs as a Markdown bullet list, improving readability. | Thanks to @kunaldevsahu. #6384 |
Fixed a typo in the CronJob list's lastScheduleTime accessor so the Last Schedule column can now be sorted and filtered correctly. |
Thanks to @skools-here. #6383 |
Fixed a regression where searching for a namespace name flooded results with every resource in that namespace; the 'Set namespace' shortcut now appears correctly and only once.
π Bug fixes (part 5 of 11)
Fixed a stale WebSocket subscription in useKubeObject when navigating between resources of the same kind, ensuring live updates reflect the correct resource. |
Thanks to @Adii-45. #6345 |
Fixed PortForward tooltip translation, added secure rel attributes to external links, and hardened localStorage parsing to prevent crashes or UI desync on failures. |
Thanks to @KumarADITHYA123. #6341 |
Wrapped recentClusters localStorage reads in try/catch to prevent app startup crashes when stored data is corrupted or unreadable. |
Thanks to @Kakumanu-Harshitha. #6310 |
Guarded useLocalStorageState against corrupted data and QuotaExceededError, preventing blank-screen crashes across 13 components that rely on it. |
Thanks to @Kakumanu-Harshitha. #6307 |
| Fixed frontend test failures on Node.js 24 caused by an AbortSignal incompatibility between jsdom, nock, and the native Request implementation. | Thanks to @vanshika2720. #6299 |
Hardened loadTableSettings and storeTableSettings against corrupt localStorage data, preventing blank-screen crashes on all resource list views. |
Thanks to @Kakumanu-Harshitha. #6298 |
Fixed duplicate HTML id attribute in TimezoneSelect Autocomplete to prevent conflicts when both TimezoneSelect and Chooser are rendered on the same page. |
Thanks to @Priyanshu-rgbb. #6281 |
π Bug fixes (part 6 of 11)
Fixed parseCpu() to use parseFloat so decimal CPU values like 0.5 or 1.5 cores are parsed correctly instead of being silently truncated. |
Thanks to @xonas1101. #6259 |
| Fixed 'Phase: undefined' display in the Project Resources tab by falling back to 'Unknown' when a pod's phase is not yet reported. | Thanks to @krsatyamthakur-droid. #6257 |
Fixed Job detail page incorrectly showing Duration: 0s for still-running jobs; the duration row is now hidden until the job completes. |
Thanks to @xonas1101. #6237 |
Fixed a nil pointer dereference panic in OidcConfig() when AuthInfo is nil, preventing crashes during token-based or unresolved-user authentication. |
Thanks to @Anjali-Chauhan1. #6235 |
Replaced bare fmt.Println calls in backend startup with structured logging so startup messages are now captured consistently by the logger. |
Thanks to @Rucha0901. #6224 |
| Fixed the YAML/JSON editor scrolling back to the top on validation errors, so users editing large manifests no longer lose their position while typing. | Thanks to @krsatyamthakur-droid. Also thanks to @prisha-sh for reporting the issue. #6209 |
| Cluster connection warning bar is now dismissible, shows the real failure reason with an actionable link, and no longer overlaps window controls. | Thanks to @Anjali-Chauhan1. Also thanks to @rnc for reporting the issue. #6206 |
Fixed a crash in Chrome when the system timezone resolves to an unrecognized identifier like Etc/Unknown, preventing a RangeError on affected Linux systems. |
Thanks to @bhuvan-somisetty. Also thanks to @adriansev for reporting the issue. #6204 |
Fixed a React hooks violation in CreateNamespaceButton by deriving validation state during render instead of via useEffect, eliminating the stale-state bug. |
Thanks to @Shahazadi-Shaguftha-Syed. #6192 |
| Fixed Jobs, CronJobs, and JobSet overview charts that were always stuck at 100% healthy by adding correct status logic for workloads without replica fields. | Thanks to @xonas1101. #6185 |
Cluster connection warning bar is now dismissible, shows the real failure reason with an actionable link, and no longer overlaps window controls.
π Bug fixes (part 7 of 11)
Fixed OIDC login 404s in local dev by correcting the proxy path from /auth to /auth/, and enforced LF line endings for TS/JS/JSON files. |
Thanks to @kjosh-bcvmw. #6184 |
Fixed a crash when loading kubeconfigs containing non-Latin1 characters (e.g. Chinese cluster names) by replacing btoa() with UTF-8-safe base64 helpers. |
Thanks to @Anjali-Chauhan1. Also thanks to @youngledo for reporting the issue. #6178 |
| Fixed the Activity tab title for workload logs so it is now properly localized instead of always showing a hardcoded English 'Logs: ' prefix. | Thanks to @Adii-45. #6171 |
| Container status tooltips in the Pods list are now translated and respect the user's configured timezone instead of always showing English text and UTC times. | Thanks to @krsatyamthakur-droid. #6168 |
| Fixed a translation key case mismatch in LogsButton so the correct localized string is now displayed. | Thanks to @srajang1805. #6163 |
| Fixed broken frontend snapshot tests on main caused by a merge conflict with outdated snapshots. | Thanks to @illume. #6160 |
Fixed a variable name typo (namepsace β namespace) and removed dead commented-out code in NodeShellAction with no functional changes. |
Thanks to @srajang1805. #6159 |
| Added optional chaining to KubeObject subclasses so the UI gracefully handles incomplete Kubernetes object data instead of throwing TypeErrors. | Thanks to @Psykii22. #6145 |
| Fixed a typo in the node drain status error message ('repsone' β 'response') for clearer error reporting. | Thanks to @Rucha0901. #6141 |
π Bug fixes (part 8 of 11)
| Isolated TestDynamicClustersKubeConfig to a temp directory so test runs no longer pollute the user's real Headlamp config. | Thanks to @Athang69. Also thanks to @sniok for reporting the issue. #6136 |
| Fixed a spelling mistake ('listernerApi' β 'listenerApi') in headlampEventSlice for cleaner, more readable code. | Thanks to @rutujdhawale. #6131 |
| Fixed a cache-key collision in k8cache by percent-encoding literal '+' characters so the '+' delimiter is no longer ambiguous with field content. | Thanks to @sid200727. #6127 |
| Fixed a Storybook startup failure caused by a circular dependency on Node story helpers, allowing all stories to load correctly. | Thanks to @mahesh-09-12. #6126 |
Replaced loose any typing on DocsViewer's docSpecs prop with a strict type, improving type safety and editor autocompletion. |
Thanks to @r0hansaxena. #6098 |
| Fixed the CRD Details Versions table incorrectly showing the storage value in the Served column instead of the served value. | Thanks to @mahesh-09-12. #6095 |
| Fixed a rules-of-hooks violation in AuthVisible that could cause unexpected behavior by ensuring all hooks run before any early returns. | Thanks to @therealharshit. Also thanks to @illume for reporting the issue. #6092 |
Centralized the hardcoded backend base URL into a single API_BASE constant across Storybook stories, making future URL changes a one-line update. |
Thanks to @xonas1101. #6088 |
| Wrapped hardcoded English strings on the Custom Resource Instances page with i18n so they are now correctly translated with the rest of the UI. | Thanks to @krsatyamthakur-droid. #6087 |
π Bug fixes (part 9 of 11)
| Fixed a react-hooks/exhaustive-deps lint suppression in ViewButton by using a ref for the initial toggle value, making the effect correctly dependency-safe. | Thanks to @JoSParker. #6086 |
| Fixed Rules of Hooks violations in RestartButton by moving all hook calls before the early-return guard, preventing potential runtime errors. | Thanks to @nabrahma. Also thanks to @illume for reporting the issue. #6066 |
| Fixed security vulnerabilities by updating npm dependencies via audit fix. | Thanks to @skoeva. #6055 |
Replaced Math.random() with React 18's useId() in the useId utility, fixing a react-hooks/purity lint violation during render. |
Thanks to @Shahazadi-Shaguftha-Syed. #6041 |
| Added a regression test for undefined i18n locale handling in ThemeProviderNexti18n, preventing reintroduction of the Firefox crash fixed in #5802. | Thanks to @mahesh-09-12. #6026 |
| Fixed stale YAML data in the resource editor by fetching the latest object from the API before opening, ensuring edits always reflect the current state. | Thanks to @ayushmaan-16. #6014 |
| Added regression tests for the LimitRangeDetails component to verify Container Limits and other DetailsGrid configuration are correctly exposed. | Thanks to @mahesh-09-12. #6013 |
| Fixed getPercentStr() so whole-number percentages no longer display a spurious trailing .0, keeping metric displays clean and readable. | Thanks to @xonas1101. #6000 |
Fixed a crash on the Gateways page when a Gateway resource has no spec.listeners, preventing a blank view for users with incomplete Gateway objects. |
Thanks to @Anjali-Chauhan1. Also thanks to @jianchao990-bit for reporting the issue. #5996 |
| Log viewer preferences for auto-scroll (follow) and show-timestamps are now saved to localStorage so they persist across browser sessions. | Thanks to @Athang69. Also thanks to @prisha-sh for reporting the issue. #5993 |
Fixed a crash on the Gateways page when a Gateway resource has no spec.listeners, preventing a blank view for users with incomplete Gateway objects.
π Bug fixes (part 10 of 11)
| Port-forward requests using an already-active ID now return HTTP 409 Conflict instead of silently overwriting the session, preventing port and goroutine leaks. | Thanks to @Nyx128. #5990 |
Added regression tests for the IngressDetails component covering metadata, TLS configuration, and rules rendering to guard against future regressions. |
Thanks to @mahesh-09-12. #5966 |
| Fixed row selections disappearing after polling refreshes in resource tables when any row lacks a metadata.uid, keeping selections stable across data refreshes. | Thanks to @WasThatRudy. Also thanks to @prisha-sh for reporting the issue. #5952 |
Fixed open-redirect bypass in isValidRedirectPath by stripping whitespace and decoding URL-encoded sequences before protocol checks, preventing malicious redirect exploits. |
Thanks to @Athang69. #5920 |
| Fixed malformed i18n interpolation syntax in CreateNamespaceButton, eliminating duplicate translation keys during extraction. | Thanks to @xonas1101. #5919 |
Fixed Restart button visibility using patch permission instead of update, so users see and can use the button only when they have the correct access. |
Thanks to @mishradwaterlaw. Also thanks to @wiswesser for reporting the issue. #5908 |
Replaced deprecated addListener/removeListener calls in the color-scheme hook with the standard addEventListener API, removing browser deprecation warnings. |
Thanks to @YadavAkhileshh. #5785 |
π Bug fixes (part 11 of 11)
Removed an unused themeName dependency from the MUI theme hook, eliminating a spurious eslint warning and avoiding unnecessary theme recomputation. |
Thanks to @kishore08-07. #5768 |
Fixed incorrect useMemo and useEffect dependencies in NumRowsInput so rows-per-page settings are computed and applied correctly when options change. |
Thanks to @kishore08-07. #5767 |
| Fixed a cache authorization bug where named Kubernetes resource requests used the object name instead of the resource type in access reviews, preventing incorrect authorization failures. | Thanks to @harrshita123. #5719 |
| Fixed service proxy incorrectly converting upstream non-200 responses into 500 errors, so real upstream status codes like 404 are now accurately passed through. | Thanks to @harrshita123. #5589 |
| Fixed theme name capitalization mangling multi-word custom theme names in the Settings picker and Search bar. | Thanks to @dabico. #5549 |
| Fixed a stale closure bug in the Resource Map so node topology now correctly updates when cluster nodes are added or removed. | Thanks to @KumarADITHYA123. #5389 |
Aligned the Pods list's Load more control with the right-side header actions while keeping the create button beside the title. |
Thanks to @rootp1. #6721 |
| Fixed Resource Map viewport fitting, namespace simplification, and resize stability, while hiding performance diagnostics unless explicitly enabled. | Thanks to @illume. #6718 |
| Fixed shared WebSocket watches so all subscribers receive updates and one subscriber cannot disconnect the others. | Thanks to @rootp1. #6719 |
π Security
| Release checksums are now signed with cosign keyless signing, improving OpenSSF Scorecard's Signed-Releases score for future releases. | Thanks to @Athang69. #6656 |
| Updated backend dependencies (Go, oras-go, grpc, crypto, text) and frontend i18next-fs-backend, plus refreshed Dockerfile node image digests. | Thanks to @skoeva. #6330 |
| Bumped Alpine to 3.24.1, containerd to 1.7.33, and Go to 1.26.4 in the Dockerfile to patch known vulnerabilities. | Thanks to @skoeva. #6135 |
| Bumped undici to 6.27.0 in app and 7.28.0 in headlamp-plugin to address security vulnerabilities. | Thanks to @skoeva. #6133 |
| Moved cluster hooks to break a circular import that previously caused CodeQL's TypeScript extractor to hang, enabling SAST scanning. | Thanks to @Athang69. #6076 |
| Expanded backend fuzz test coverage for parser and normalizer code paths, improving reliability and security of backend input handling. | Thanks to @tejhan. #6063 |
Release checksums are now signed with cosign keyless signing, improving OpenSSF Scorecard's Signed-Releases score for future releases.
βΏ Accessibility
| Fixed xterm terminal e2e tests that were unconditionally skipping all cases, so theme and accessibility assertions now actually run. | Thanks to @Anjali-Chauhan1. Also thanks to @unlikelyzero for reporting the issue. #6666 |
| Enabled automated accessibility checks on the plugin settings and details pages in end-to-end tests, catching a11y regressions earlier. | Thanks to @PrakharJain345. #6213 |
Replaced native browser title tooltips across the UI with Headlamp's styled tooltips for a consistent look and feel throughout the application. |
Thanks to @xonas1101. Also thanks to @CygnusMaximillian for reporting the issue. #5977 |
Restored the macOS desktop Zoom In keyboard shortcut (Cmd+Plus), fixing a regression that broke the accelerator while Zoom Out and Reset Zoom continued to work. |
Thanks to @rootp1. #6714 |
| Fixed "User-installed" plugin chip text color to meet WCAG AA contrast requirements, improving readability in both light and dark themes. | Thanks to @vtushar06. Also thanks to @illume for reporting the issue. #6110 |
| Removed incorrect aria-label overrides from ConfirmDialog, RollbackDialog, and ScaleMultipleButton so screen readers now announce the visible button text instead of raw identifiers. | Thanks to @unlikelyzero. #6653 |
| Fixed Tab key navigation on the Create Resource page so all tabs and panel content are keyboard-accessible without requiring a mouse. | Thanks to @vyncent-t. #6597 |
Wrapped the ActivityBar Close button's aria-label in t() so screen readers announce it in the user's chosen language. |
Thanks to @krsatyamthakur-droid. #6357 |
Resource Map zoom/fit controls now have translated aria-label values, improving screen-reader experience for non-English users. |
Thanks to @Kakumanu-Harshitha. #6317 |
| Fixed aria-controls on EditorDialog buttons (Undo, Dry Run, Save & Apply) to reference the actual textarea, improving screen-reader accessibility. | Thanks to @Suyog241005. #5956 |
| Fixed Space key not activating graph nodes in the Map view by correcting the key check from 'Space' to ' ', restoring full keyboard navigation for keyboard users. | Thanks to @vtushar06. #5923 |
| Integrated automated accessibility (a11y) checks via axe-core/playwright and stabilized pluginctl tests by fixing broken dependencies and locale-dependent selectors. | Thanks to @vishnukothakapu. #5413 |
| Extended E2E accessibility scanning to the Services and Security pages, broadening automated a11y coverage across key navigation areas. | Thanks to @srajang1805. #6016 |
π Documentation
Fixed a typo in the log function docstring so the logger package documentation correctly references the unexported function name. |
Thanks to @saiashok0981. #6576 |
| Expanded in-cluster docs with working YAML examples for using a custom kubeconfig, correcting misleading claims that caused user confusion. | Thanks to @akshattalwar001. Also thanks to @illume for reporting the issue. #6538 |
Replaced @todo placeholders with proper JSDoc comments on frontend API endpoints, improving the developer experience when working with the API layer. |
Thanks to @Psykii22. #6347 |
| Added an Example MCP Servers section to the MCP support docs with ready-to-use configurations for three local stdio servers. | Thanks to @vtushar06. #6060 |
π Plugins
Plugins can now register non-clickable section headers in the sidebar using registerSidebarEntry with entryType: 'subheader' to better organize navigation. |
Thanks to @Soli0222. #6108 |
Added a config.staticPlugins.enabled Helm value so users can officially disable the bundled Prometheus and other static plugins without undocumented workarounds. |
Thanks to @Anjali-Chauhan1. Also thanks to @KhaledELG for reporting the issue. #6142 |
| Plugins can now filter or hide HOME sidebar menu items using the new registerHomeSidebarEntryFilter API, matching existing in-cluster sidebar capabilities. | Thanks to @Suyog241005. Also thanks to @danp60 for reporting the issue. #6111 |
| Plugin installation now works behind corporate TLS-inspecting proxies on Windows by trusting OS-level CA certificates and surfacing clearer TLS error messages. | Thanks to @Anjali-Chauhan1. Also thanks to @junkiebev for reporting the issue. #6379 |
Fixed deletion of catalog-installed plugins migrated before user-plugins/ existed, so DELETE /plugins/{name}?type=user no longer fails with a 'not found' error. |
Thanks to @Pritz395. Also thanks to @skoeva for reporting the issue. #6573 |
Migrated headlamp-plugin tsconfig moduleResolution from deprecated node to bundler, eliminating the deprecation warning and aligning with the existing module settings. |
Thanks to @Athang69. #6515 |
| Added try/catch around JSON.parse in the plugin-manager IPC handler so parse errors are returned to the renderer instead of crashing as unhandled rejections. | Thanks to @krsatyamthakur-droid. #6471 |
| Removed deprecated 'baseUrl' and 'node10' moduleResolution from the plugin TypeScript config, aligning path resolution with TypeScript 6 and Vite bundling. | Thanks to @Athang69. Also thanks to @sniok for reporting the issue. #6439 |
| Plugin load failures now show an error notification instead of silently failing, so users are informed when plugins cannot be loaded. | Thanks to @krsatyamthakur-droid. #6351 |
| Plugin settings stored in localStorage are now safely parsed, preventing crashes when the stored JSON is corrupt or malformed. | Thanks to @xonas1101. #6152 |
Fixed HEADLAMP_CONFIG_WATCH_PLUGINS_CHANGES being ignored in-cluster so plugin watch behavior now correctly follows the environment variable or CLI flag. |
Thanks to @harrshita123. #5591 |
| The plugins container build now matches the host platform by default, fixing mismatched architectures on Apple Silicon Macs and allowing the platform to be overridden via environment variable. | Thanks to @unlikelyzero. #6638 |
| Added error handling around JSON.parse in the frontend pluginManager so malformed IPC responses no longer cause unhandled exceptions or skip cleanup. | Thanks to @Khizarshah01. #6630 |
| Plugin commands now run with the user's login-shell environment, allowing desktop app launches to resolve executables installed outside the GUI process PATH. | Thanks to @illume. #6598 |
| Replaced deprecated fs.rmdirSync calls with fs.rmSync in plugin management code to eliminate Node.js deprecation warnings. | Thanks to @skools-here. #6073 |
| Bumped headlamp-plugin to version 0.14.0. | Thanks to @illume. #5579 |
Plugins can now register non-clickable section headers in the sidebar using registerSidebarEntry with entryType: 'subheader' to better organize navigation.
π» Development (part 1 of 8)
| Updated the e2e-tests README to accurately document the two-cluster kind setup required, preventing misleading test failures that resemble product bugs. | Thanks to @unlikelyzero. #6658 |
| Fixed the desktop e2e suite so it runs correctly by following the documented steps, resolving a missing script error and an undocumented setup requirement. | Thanks to @unlikelyzero. #6654 |
| Moved the canvas mock into the shared Vitest setup, eliminating redundant per-test imports and reducing frontend test harness noise. | Thanks to @rootp1. #6569 |
| Added gambtho as a project reviewer. | Thanks to @gambtho. #6406 |
| Added skoeva to the headlamp-maintainers list in OWNERS_ALIASES. | Thanks to @skoeva. #6336 |
Added backend tests for RemoveContextFromFile covering missing-context and empty-path edge cases, improving kubeconfig error-handling coverage. |
Thanks to @CygnusMaximillian. #6496 |
| Fixed the health-check polling interval not resetting after cluster recovery, so the backoff no longer grows indefinitely without a manual retry. | Thanks to @xonas1101. #6446 |
π» Development (part 2 of 8)
| Fixed Pod detailed status showing 'Signal:undefined' for containers that exit without a signal, correctly displaying the exit code instead. | Thanks to @ssz2605. #6442 |
| Kubeconfig cluster load failures now log at console.error level instead of console.debug, making the root cause visible in the browser console. | Thanks to @Khizarshah01. #6435 |
Replaced context.TODO() with context.Background() in service proxy tests, aligning test code with Go best practices. |
Thanks to @ssz2605. #6421 |
Removed an unreachable duplicate cache-hit check in getDetailedStatus(), cleaning up dead code without changing behaviour. |
Thanks to @skools-here. #6405 |
Added unit tests for the Context.AuthType() method in the kubeconfig package, increasing backend test coverage. |
Thanks to @CygnusMaximillian. #6375 |
| Global search now matches resources by namespace and displays the namespace alongside the resource kind, making it easier to distinguish resources with the same name. | Thanks to @Priyanshu-rgbb. #6356 |
Fixed renameCluster backend handler to correctly return errors on duplicate cluster names and cache update failures instead of silently reporting success. |
Thanks to @vtushar06. #6302 |
| Restored translation strings accidentally cleared by a previous revert, fixing missing UI text across multiple locales. | Thanks to @sniok. #6271 |
Added unit tests for the OIDCAuth component covering redirect rendering, local storage auth status, and query parameter handling. |
Thanks to @PrakharJain345. #6268 |
π» Development (part 3 of 8)
Cleaned up TypeScript return-type annotations in frontend API modules by adding explicit types and removing stale @todo comments; no behavior change. |
Thanks to @therealharshit. #6244 |
| Fixed stale cache data for named GET and all-namespace list requests by ensuring informer events now invalidate those cache keys alongside list-shaped keys. | Thanks to @Pragati5-DEBUG. #6230 |
Extracted server startup and shutdown logic from StartHeadlampServer into a dedicated runServer helper, improving code clarity without changing behavior. |
Thanks to @srajang1805. #6217 |
Moved OIDC token refresh middleware into the dedicated auth package, improving code organisation without changing authentication behavior. |
Thanks to @srajang1805. #6211 |
Refactored OIDCAuth internals by extracting a shared AUTH_STATUS_KEY constant and fixing the useEffect dependency array; no behaviour changes. |
Thanks to @Priyanshu-rgbb. #6203 |
| Windows x64 and arm64 release builds now run independently so a failure in one architecture no longer cancels the other, avoiding lost artifacts and full workflow reruns. | Thanks to @skoeva. #6181 |
| Bumped service-appprotocol chart version to 0.43.0 to fix failing CI chart tests. | Thanks to @skoeva. #6165 |
Added an explicit return type to KubeObject.apiList, replacing the implicit any inference to improve type safety with no runtime changes. |
Thanks to @somaz94. #6148 |
| Added unit tests for buildHeadlampCFG to ensure configuration flags are correctly mapped to the HeadlampCFG struct. | Thanks to @CygnusMaximillian. #6121 |
| LimitRange detail view now displays maxLimitRequestRatio alongside other constraints for a more complete resource overview. | Thanks to @srajang1805. #6116 |
π» Development (part 4 of 8)
| Added a confirmation warning when deleting protected Kubernetes system namespaces (default, kube-system, etc.) to prevent accidental cluster damage. | Thanks to @Anjali-Chauhan1. Also thanks to @hstarorg for reporting the issue. #6106 |
| Added a test for MarshalCustomObject error handling to ensure invalid JSON is correctly caught and surfaced in the backend. | Thanks to @CygnusMaximillian. #6102 |
| Added JSON marshaling/unmarshaling unit tests for ClusterReq to improve backend reliability and catch serialization regressions. | Thanks to @CygnusMaximillian. #6101 |
| Added unit tests for the Ingress model class covering address, host, and rule parsing to improve frontend reliability. | Thanks to @srajang1805. #6082 |
| Added unit tests for DaemonSet and StatefulSet model classes, improving confidence in container and node selector logic. | Thanks to @srajang1805. #6081 |
| Mac binaries are now code-signed by default when triggering app builds, ensuring users receive trusted macOS releases. | Thanks to @sniok. #6079 |
| Fixed compareUnits to use parseFloat instead of parseInt so fractional resource values like CPU millicores are compared correctly. | Thanks to @Suyog241005. #6068 |
Added unit tests for buildTelemetryConfig and loadOidcCACert helper functions, improving backend config test coverage. |
Thanks to @aryanraj45. #6052 |
Added unit test for returnGVRList in the k8s cache invalidation package, closing a previously untested code path. |
Thanks to @CygnusMaximillian. #6048 |
π» Development (part 5 of 8)
| Added test coverage for PriorityClass, PodDisruptionBudget, and HorizontalPodAutoscaler components, verifying columns, extraInfo, and fallback values. | Thanks to @aryanraj45. #6047 |
| Added test coverage for Lease, RuntimeClass, and StorageClass components, verifying their resource-specific column and detail configurations. | Thanks to @aryanraj45. #6042 |
Simplified OIDCTokenRefreshMiddleware by inlining helper functions and consolidating repeated metric calls into a single deferred call, reducing code duplication. |
Thanks to @skoeva. #6039 |
| Added 18 unit tests for the Service model covering external addresses, ports, formatted ports, and selectors, improving confidence in Service data handling. | Thanks to @srajang1805. #6017 |
| Replaced %v with %w in backend fmt.Errorf calls so error chains are preserved, enabling proper errors.Is and errors.As unwrapping throughout the backend. | Thanks to @Psykii22. #5997 |
| Node roles in the list view are now separated by ", " instead of ",", matching the formatting on the node details page for a consistent look. | Thanks to @skoeva. #5994 |
| Added unit tests for the k8cache resource-filtering logic, ensuring the goroutine-reduction behaviour introduced in #4670 is verified by deterministic tests. | Thanks to @Pragati5-DEBUG. #5957 |
| Localized the 'Lines' label and 'All' menu item in the logs viewer Lines selector so they are now translated consistently with the rest of the toolbar. | Thanks to @vtushar06. #5944 |
π» Development (part 6 of 8)
Added unit tests for the recentClusters helper, covering deduplication, cluster cap, and edge cases to prevent silent regressions. |
Thanks to @RajPrakash681. #5831 |
Added unit tests for the clusterSettings helper, guarding against silent regressions in cluster-specific configuration storage used across 14 files. |
Thanks to @RajPrakash681. #5829 |
Switched kubeconfig error formatting from %v to %w, enabling proper error unwrapping with errors.Is() and errors.As(). |
Thanks to @vmridul. #5786 |
Added negative tests confirming that mutating and proxy endpoints correctly reject callers missing a valid X-HEADLAMP_BACKEND-TOKEN header, guarding against auth regressions. |
Thanks to @vyncent-t. #5657 |
Fixed OIDC login to return a proper 500 Internal Server Error when state generation fails, and made the random source injectable for reliable testing. |
Thanks to @harrshita123. #5643 |
Hardened the parseKubeConfig test to assert the handler writes exactly one response, preventing silent double-write regressions from going undetected. |
Thanks to @harrshita123. #5599 |
| Added regression tests ensuring unavailable cluster errors are non-selectable and forbidden resource requests do not retry unnecessarily. | Thanks to @harrshita123. #5535 |
π» Development (part 7 of 8)
| Added Storybook snapshot stories for the ClusterBadge sidebar component, giving it automated visual regression coverage for the first time. | Thanks to @xonas1101. #6482 |
| Added Storybook snapshot stories for the sidebar VersionButton in both expanded and collapsed states, closing the gap in snapshot test coverage. | Thanks to @xonas1101. #6448 |
Added Storybook stories for ConditionList, covering its status-colour mapping and render output to include it in snapshot test coverage. |
Thanks to @xonas1101. #6396 |
Added Storybook stories for PhaseLabel covering all colour-mapping branches, which also serve as snapshot tests to prevent regressions. |
Thanks to @xonas1101. #6371 |
| Added Storybook snapshot stories for ThemePreview, NumRowsInput, and other Settings widgets, increasing test coverage for that area. | Thanks to @xonas1101. #6316 |
| Added Storybook stories for the ServiceAccount Details view, enabling visual regression testing and easier isolated development of that component. | Thanks to @bhuvan-somisetty. Also thanks to @Shahazadi-Shaguftha-Syed for reporting the issue. #6295 |
| Added Storybook stories for the node UpgradeVisualizationPanel, covering upgrading and idle states to enable visual regression testing. | Thanks to @xonas1101. #6285 |
Added dedicated Storybook stories for SectionFilterHeader, improving visual regression coverage and enabling isolated development of filter header states. |
Thanks to @xonas1101. #6262 |
| Consolidated Label component Storybook stories into a single file and added missing variants for more complete visual coverage. | Thanks to @jainarjav80-sys. Also thanks to @xonas1101 for reporting the issue. #6195 |
| Added Storybook stories and storyshots for VolumeAttributesClass list and detail views to catch UI regressions early. | Thanks to @Suhani95. #6078 |
Added Storybook stories for the JobDetails component, enabling snapshot-based regression testing for the job details view. |
Thanks to @xonas1101. #6051 |
π» Development (part 8 of 8)
Replaced deprecated github.com/pkg/errors with Go's standard errors and fmt.Errorf(%w), removing an unnecessary third-party dependency. |
Thanks to @Psykii22. #6045 |
Added Storybook stories for DryRunPreviewDialog covering open, closed, and large YAML preview states, making it easier to visually validate dialog behaviour. |
Thanks to @Suhani95. #6032 |
| Added Storybook snapshot stories for the DaemonSet Details view, improving test coverage for Update Strategy, Selector, Tolerations, and Containers sections. | Thanks to @xonas1101. #6030 |
| Added a Storybook story for the 404 NotFoundComponent, giving it snapshot-based regression coverage alongside the rest of the component library. | Thanks to @xonas1101. #5979 |
Introduced shared ConditionList, PhaseLabel components and a getReadyCondition utility to eliminate duplicated status-rendering code across multiple resource views. |
Thanks to @Athang69. #5968 |
| Added Storybook snapshot stories for RBAC role components (List, Details, BindingList, BindingDetails), giving these views regression test coverage for the first time. | Thanks to @xonas1101. #5961 |
| Added Storybook stories for ServiceAccount Details and List views, providing snapshot-based regression coverage for those components. | Thanks to @Shahazadi-Shaguftha-Syed. #5955 |
| Added Storybook stories for GlobalSearchContent covering empty input, loading, and results states, enabling snapshot regression testing for the global search UI. | Thanks to @yuki681. #5945 |
| Added Storybook snapshot stories for the node Details and Charts components, adding regression coverage for CPU/memory usage charts and node detail views. | Thanks to @xonas1101. #5942 |
Added Storybook stories for the DeleteButton component, covering all main visual states to improve UI development and review. |
Thanks to @sudhidutta7694. #5893 |
Container image: π³ ghcr.io/headlamp-k8s/headlamp:v0.44.0
Desktop Apps:
π§ Flatpak / Linux (AMD64)
π§ Linux AppImage AMD64, ARM64, ARMv7l
π§ Linux Tarball AMD64, ARM64, ARMv7l
π§ Debian / Linux AMD64
π Mac (AMD64)
π Mac (ARM/M1-M5)
π¦ Windows (AMD64)
π¦ Windows (ARM64)