quarkusio/quarkus · error · RuntimeException

Failed to read kubeconfig file: " + kubeconfigPath

Error message

Failed to read kubeconfig file: " + kubeconfigPath

What it means

KubernetesClientUtils.createConfig builds the Kubernetes client Config. When a kubeconfig file is explicitly configured (clientConfig.kubeconfigFile()), the file must be readable; any IOException reading it aborts client creation with this RuntimeException wrapping the path.

Source

Thrown at extensions/kubernetes-client/runtime-internal/src/main/java/io/quarkus/kubernetes/client/runtime/internal/KubernetesClientUtils.java:31

public class KubernetesClientUtils {

    private static final String PREFIX = "quarkus.kubernetes-client.";

    private KubernetesClientUtils() {
    }

    public static Config createConfig(KubernetesClientConfig clientConfig) {
        io.smallrye.config.Config config = io.smallrye.config.Config.get();
        boolean globalTrustAll = config.getOptionalValue("quarkus.tls.trust-all", Boolean.class).orElse(false);
        Config base;
        if (clientConfig.kubeconfigFile().isPresent()) {
            String kubeconfigPath = clientConfig.kubeconfigFile().get();
            try {
                String kubeconfig = Files.readString(Path.of(kubeconfigPath));
                base = Config.fromKubeconfig(kubeconfig);
            } catch (IOException e) {
                throw new RuntimeException("Failed to read kubeconfig file: " + kubeconfigPath, e);
            }
        } else {
            base = Config.autoConfigure(null);
        }
        boolean trustAll = clientConfig.trustCerts().isPresent() ? clientConfig.trustCerts().get() : globalTrustAll;
        final var configBuilder = new ConfigBuilder(base).withTrustCerts(trustAll);
        clientConfig.watchReconnectInterval().ifPresent(d -> configBuilder.withWatchReconnectInterval(millisAsInt(d)));
        clientConfig.watchReconnectLimit().ifPresent(configBuilder::withWatchReconnectLimit);
        clientConfig.connectionTimeout().ifPresent(d -> configBuilder.withConnectionTimeout(millisAsInt(d)));
        clientConfig.requestTimeout().ifPresent(d -> configBuilder.withRequestTimeout(millisAsInt(d)));
        clientConfig.apiServerUrl().ifPresent(configBuilder::withMasterUrl);
        clientConfig.namespace().ifPresent(configBuilder::withNamespace);
        clientConfig.username().ifPresent(configBuilder::withUsername);
        clientConfig.password().ifPresent(configBuilder::withPassword);
        clientConfig.token().ifPresent(configBuilder::withOauthToken);
        clientConfig.caCertFile().ifPresent(configBuilder::withCaCertFile);
        clientConfig.caCertData().ifPresent(configBuilder::withCaCertData);
        clientConfig.clientCertFile().ifPresent(configBuilder::withClientCertFile);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Fix the configured path to an existing, readable kubeconfig file (ls -l <path> to verify).
  2. Ensure the file is mounted/copied into CI containers and readable by the build user.
  3. Remove the kubeconfig-file property to fall back to Config.autoConfigure (default ~/.kube/config / in-cluster config).

Example fix

// before
quarkus.kubernetes-client.kubeconfig-file=/home/ci/.kube/nonexistent-config
// after
quarkus.kubernetes-client.kubeconfig-file=/home/ci/.kube/config
Defensive patterns

Strategy: validation

Validate before calling

// Verify kubeconfig readability before creating the client
String kubeconfigFile = clientConfig.kubeconfigFile().orElse(null);
if (kubeconfigFile != null) {
    Path p = Path.of(kubeconfigFile);
    if (!Files.isRegularFile(p) || !Files.isReadable(p)) {
        throw new IllegalStateException("kubeconfig file missing or unreadable: " + kubeconfigFile);
    }
    Config.fromKubeconfig(Files.readString(p)); // fail fast on malformed YAML too
}

Try / catch

try {
    client = KubernetesClientUtils.createClient(clientConfig);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Failed to read kubeconfig file:")) {
        LOGGER.errorf("Fix quarkus.kubernetes-client.kubeconfig-file: %s", e.getMessage());
        // fallback to auto-configured (in-cluster) credentials
        client = new KubernetesClientBuilder().build();
    } else { throw e; }
}

Prevention

When it happens

Trigger: quarkus.kubernetes-client.kubeconfig-file (via clientConfig.kubeconfigFile()) points to a file that does not exist, is a directory, or is unreadable; createConfig is invoked by createClient when building the client.

Common situations: Typo or wrong absolute path in kubeconfig-file config; file generated at runtime but not yet present; CI container lacking the mounted kubeconfig; permission issues after copying credentials.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/da9388cb4cbe1115. Report an issue: GitHub.