Skip to content

helm-controller panics on hooks with helm.sh/hook-output-log-policy (nil HookOutputFunc) #1562

Description

@alpaca-serious

Describe the bug

helm-controller v1.6.3 panics during Helm upgrade when a chart hook Pod/Job has
helm.sh/hook-output-log-policy. The process exits 2 (SIGSEGV), the release is
left pending-upgrade, and the next reconcile unlocks and retries.
Not OOM. lastState.terminated.reason=Error, exitCode=2.

Stack

panic: runtime error: invalid memory address or nil pointer dereference helm.sh/helm/v4/pkg/kube.(*Client).OutputContainerLogsForPodList helm.sh/helm/v4/pkg/action.(*Configuration).outputLogsByPolicy helm.sh/helm/v4/pkg/action.(*Configuration).execHook

OutputContainerLogsForPodList is called with a nil writerFunc
(cfg.HookOutputFunc).

Why

Helm CLI Init() sets HookOutputFunc to io.Discard.
NewConfiguration() does not. helm-controller ConfigFactory.Build() uses
NewConfiguration() and never sets HookOutputFunc.

Charts that set helm.sh/hook-output-log-policy: hook-succeeded,hook-failed
work with helm upgrade and crash under Flux.

Version

  • helm-controller: v1.6.3 (fluxcd/helm-controller)
  • Helm SDK: v4.2.2 (replace github.com/fluxcd/helm/v4 v4.2.4-flux.1)

Repro

  1. HelmRelease for a chart with a post-upgrade hook Pod annotated
    helm.sh/hook-output-log-policy: hook-succeeded,hook-failed
    (example: Archestra networkPolicyProbe).
  2. Let helm-controller reconcile an upgrade.
  3. Controller panics; release stays pending-upgrade.

Workaround

Disable the hook in values (archestra.networkPolicyProbe.enabled: false)
so the annotation is not rendered.

Expected

No panic. Default HookOutputFunc to io.Discard (or nil-check in Helm)
and complete the upgrade.

Helm controller log

Details {"level":"info","ts":"2026-08-18T19:02:54.xxxZ","msg":"release in-sync with desired state","controller":"helmrelease","controllerGroup":"helm.toolkit.fluxcd.io","controllerKind":"HelmRelease","HelmRelease":{"name":"","namespace":"flux-system"},"namespace":"flux-system","name":"","reconcileID":""} {"level":"error","ts":"2026-08-18T19:02:54.xxxZ","msg":"Reconciler error","controller":"helmrelease","controllerGroup":"helm.toolkit.fluxcd.io","controllerKind":"HelmRelease","HelmRelease":{"name":"","namespace":"flux-system"},"namespace":"flux-system","name":"","reconcileID":"","error":"terminal error: exceeded maximum retries: cannot remediate failed release"} {"level":"info","ts":"2026-08-18T19:02:54.xxxZ","msg":"release locked: release with status 'pending-upgrade'","controller":"helmrelease","controllerGroup":"helm.toolkit.fluxcd.io","controllerKind":"HelmRelease","HelmRelease":{"name":"","namespace":"flux-system"},"namespace":"flux-system","name":"","reconcileID":""} {"level":"info","ts":"2026-08-18T19:02:54.xxxZ","msg":"running 'unlock' action with timeout of 5m0s","controller":"helmrelease","controllerGroup":"helm.toolkit.fluxcd.io","controllerKind":"HelmRelease","HelmRelease":{"name":"","namespace":"flux-system"},"namespace":"flux-system","name":"","reconcileID":""} {"level":"info","ts":"2026-08-18T19:02:54.xxxZ","msg":"release not managed by controller: found existing release in storage","controller":"helmrelease","controllerGroup":"helm.toolkit.fluxcd.io","controllerKind":"HelmRelease","HelmRelease":{"name":"","namespace":"flux-system"},"namespace":"flux-system","name":"","reconcileID":""} {"level":"info","ts":"2026-08-18T19:02:54.xxxZ","msg":"running 'upgrade' action with timeout of 5m0s","controller":"helmrelease","controllerGroup":"helm.toolkit.fluxcd.io","controllerKind":"HelmRelease","HelmRelease":{"name":"","namespace":"flux-system"},"namespace":"flux-system","name":"","reconcileID":""} panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1add3f0]

goroutine 1895 [running]:
helm.sh/helm/v4/pkg/kube.(*Client).OutputContainerLogsForPodList(...)
helm.sh/helm/v4@v4.2.2/pkg/kube/client.go:1267 +0x250
helm.sh/helm/v4/pkg/action.(*Configuration).outputContainerLogsForListOptions(...)
helm.sh/helm/v4@v4.2.2/pkg/action/hooks.go:274 +0xfe
helm.sh/helm/v4/pkg/action.(*Configuration).outputLogsByPolicy(...)
helm.sh/helm/v4@v4.2.2/pkg/action/hooks.go:262 +0x3b0
helm.sh/helm/v4/pkg/action.(*Configuration).execHookWithDelayedShutdown.func2()
helm.sh/helm/v4@v4.2.2/pkg/action/hooks.go:155 +0x107
helm.sh/helm/v4/pkg/action.(*Configuration).execHook(...)
helm.sh/helm/v4@v4.2.2/pkg/action/hooks.go:49 +0x85
helm.sh/helm/v4/pkg/action.(*Upgrade).releasingUpgrade(...)
helm.sh/helm/v4@v4.2.2/pkg/action/upgrade.go:510 +0x665
created by helm.sh/helm/v4/pkg/action.(*Upgrade).performUpgrade in goroutine 288
helm.sh/helm/v4@v4.2.2/pkg/action/upgrade.go:418 +0x1685

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions