Skip to main content
DevOps Insightsguides & answers

Helm · troubleshooting

Error: Kubernetes cluster unreachable

Helm could not reach a cluster: localhost:8080 in the message means it found no kubeconfig at all, any other address means nothing answered there. In Terraform it usually means the Helm provider has no cluster settings yet.

Reproduced on Helm 3.18.2, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 10 sections

Before you start

  • The exact error line, including the address Helm tried.
  • kubectl, to test the same kubeconfig: kubectl config current-context and kubectl get --raw /version.

Run this first

step 1 of 2
helm list -A 2>&1 | head -1

Look for localhost:8080 (no kubeconfig) or a real server address (network or cluster)

Repeats the error with the address Helm tried.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

What does the error say after cluster unreachable?

Cause space

4 of 4 still possible

  • Helm found no kubeconfigCommon
  • The context or cluster in the kubeconfig is wrongCommon
  • The API server's address cannot be reached from hereOccasional
  • Terraform's Helm provider has no cluster settings yetCommon

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Check it with a tool

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    helm list -A 2>&1 | head -1

    Repeats the error with the address Helm tried.

    Look for localhost:8080 (no kubeconfig) or a real server address (network or cluster)

  2. Step 2

    kubectl config current-context && kubectl get --raw /version

    kubectl reads the same kubeconfig; if it fails the same way, the problem is not Helm.

    Look for A context name and a version response

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

Helm found no kubeconfig

Common

No ~/.kube/config for the user running Helm, KUBECONFIG pointing at a missing file, or a CI job, cron entry or sudo with a different HOME. Helm falls back to localhost:8080.

Confirm

echo "KUBECONFIG=${KUBECONFIG:-unset} HOME=$HOME"
kubectl config current-context

localhost:8080 in the Helm error, and kubectl reporting no current context or the same refusal

Fix

  • Point Helm at the right file: export KUBECONFIG=/path/to/config, or pass --kubeconfig.
  • In CI, create the kubeconfig in the job before Helm runs, for example aws eks update-kubeconfig --name CLUSTER or your platform's equivalent.
  • Under sudo, run Helm as your own user instead, or pass --kubeconfig explicitly.
helm list --kubeconfig ~/.kube/config

If this works, the default location or KUBECONFIG was the problem.

The context or cluster in the kubeconfig is wrong

Common

The kubeconfig exists but its current context points at a cluster that is gone, renamed, or on a network you are not on, or --kube-context names a context that is not in the file.

Confirm

kubectl config get-contexts
kubectl get --raw /version

The context you expected marked current, and kubectl failing the same way if the cluster itself is unreachable

Fix

  • Switch to the right context: kubectl config use-context NAME, or helm --kube-context NAME.
  • For a cluster that was recreated, refresh its entry with your cloud CLI rather than editing the file by hand.

The API server's address cannot be reached from here

Occasional

A private API endpoint reached from outside its network, a VPN that is down, or a firewall. The error names the real server address and ends with i/o timeout or connection refused.

Confirm

kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}{"\n"}'
curl -sk --max-time 5 "$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')/version"

No answer from the server URL from this machine

Fix

  • Run Helm from somewhere that can reach the API server (inside the VPC, over the VPN, or a runner in the cluster's network).
  • If the endpoint should be public, check its access settings in your cloud console.

Terraform's Helm provider has no cluster settings yet

Common

The provider is configured from a cluster resource or data source in the same apply. When Terraform configures the provider, those values are not known yet, so it gets an empty configuration.

Confirm

grep -n -A8 'provider "helm"' *.tf

host, token or config_path taken from a cluster created in the same configuration

Fix

  • Split it: create the cluster in one apply (or module), and deploy Helm releases in another that reads the cluster with a data source, as the Kubernetes provider's documentation recommends.
  • With Helm provider 3.x, write the settings as an attribute, kubernetes = { config_path = "~/.kube/config" }; the 2.x block form kubernetes { … } changed in 3.0.0.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

Helm talks to Kubernetes the same way kubectl does, using the kubeconfig file that says where the cluster is and how to log in. If there is no such file for the user running Helm, it falls back to an old default, a cluster on this machine at port 8080, which almost never exists, so the connection is refused. The address in the error tells you whether Helm found your settings at all.

Words used on this page

kubeconfig
The file (default ~/.kube/config, or the files in KUBECONFIG) holding clusters, users and contexts. Helm and kubectl read the same one.
Context
A named pair of cluster and user in the kubeconfig. --kube-context picks one; otherwise current-context is used.
localhost:8080
The address client-go falls back to when it has no configuration (or KUBERNETES_MASTER, if set).
What is actually happening

Reproduced on Helm 3.18.2 with an empty home directory: with no kubeconfig, and with KUBECONFIG pointing at a file that does not exist, Helm printed Error: Kubernetes cluster unreachable: Get "http://localhost:8080/version": dial tcp [::1]:8080: connect: connection refused.

That address is client-go's built-in default (or the KUBERNETES_MASTER variable), used when no configuration was found. So localhost:8080 means a missing or empty kubeconfig, not a broken cluster.

With a kubeconfig whose server has nothing listening, the error names that server's address instead, and with --kube-context set to a name that is not in the file it says context "NAME" does not exist. Each tells you something different.

In Terraform, the Helm provider reports invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable when its cluster settings are empty. The Kubernetes provider's documentation warns not to create a cluster in the same module whose outputs configure the provider, because Terraform may configure the provider before those values exist.

How to tell this is your problem
WhereWhat you see
helm install, upgrade or listError: Kubernetes cluster unreachable: Get "http://localhost:8080/version": dial tcp [::1]:8080: connect: connection refused
Same command, kubeconfig foundError: Kubernetes cluster unreachable: Get "https://API_SERVER/version": dial tcp …: i/o timeout (or connection refused)
helm --kube-contextError: Kubernetes cluster unreachable: context "NAME" does not exist
terraform plan or apply (helm_release)Error: Kubernetes cluster unreachable: invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable

How to know it is actually fixed

  • helm list -A shows releases (or an empty table) instead of the error.
  • In Terraform, terraform plan reads helm_release resources without the error.

Stopping it happening again

  • In CI, generate the kubeconfig in the job from a role, and fail early with kubectl get --raw /version before running Helm.
  • Keep cluster creation and Helm releases in separate Terraform applies or modules.

Security considerations

  • Do not copy an admin kubeconfig into a CI repository or image to fix this. Generate short-lived credentials in the job, for example with your cloud's CLI, from a role the job assumes.
  • A kubeconfig can hold a token or client key; check what it contains before attaching it to an issue.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it