Skip to content

0.44.0

Latest

Choose a tag to compare

@github-actions github-actions released this 29 Jul 07:10
7e2f255

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:

Resource Map showing 20,000+ pods with all operations under 37ms

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.

Pod list showing 1,000 of ~35,600 pods with a Load more button lots 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.

Resource table keeping important columns readable on a narrow viewport

Mobile overflow menus and terminal dialogs now use the available screen space more effectively.

Mobile overflow menu with labelled Settings and Account actions Full-screen terminal dialog using the available mobile viewport






✨ 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.

ConfigMap detail view showing binaryData field alongside data

Added a structured creation form for DaemonSets, letting users create DaemonSet resources through the UI form alongside the existing YAML editor.

DaemonSet structured creation form

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.

Monaco editor showing red squiggly underline on YAML syntax error






✨ 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.

Home page showing only recently-used clusters

Added a color-coded usage progress bar to the ResourceQuota detail view, making it easy to spot quota pressure at a glance.

ResourceQuota detail view with color-coded usage progress bar

Added a structured CreateCronJobForm for CronJob resources, letting users configure schedule, time zone, concurrency policy, and job template fields through the UI.

CronJob structured creation form

Added a tooltip disclaimer next to Events tables explaining Kubernetes Event retention lifetime, helping users understand why older events may disappear.

Events table with retention lifetime tooltip






🐞 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.

StorageClass list with Yes/No in Allow Volume Expansion column






🐞 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.

Release Notes dialog rendering HTML images from GitHub releases






🐞 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.

Global search showing only the Set namespace shortcut for a bare namespace query






🐞 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.

Dismissible cluster connection warning bar with failure reason and settings link






🐞 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.

Gateway list view rendering correctly with incomplete spec






🐞 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.

Cosign keyless signing verification for release checksums

β™Ώ 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.

Sidebar with non-clickable section headers

πŸ’» 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)