testcontainers/testcontainers-java · error · IllegalArgumentException

is not a network alias for k3s container

Error message

{} is not a network alias for k3s container

What it means

K3sContainer.generateInternalKubeConfigYaml(networkAlias) builds a kubeconfig whose API server URL points at the given network alias, which only works if that alias is actually registered as a Docker network alias on the k3s container. If the provided name is not among getNetworkAliases(), the generated kubeconfig would point at an unreachable server, so the method fails fast with IllegalArgumentException.

Solutions

  1. Add the alias before starting: k3s.withNetwork(network).withNetworkAliases("my-k3s")
  2. Use the exact alias string passed to withNetworkAliases when calling generateInternalKubeConfigYaml
  3. Verify with container.getNetworkAliases() which aliases are actually registered

Example fix

// before
K3sContainer k3s = new K3sContainer(DockerImageName.parse("rancher/k3s:v1.20.4-k3s1"));
String yaml = k3s.generateInternalKubeConfigYaml("k3s");

// after
K3sContainer k3s = new K3sContainer(DockerImageName.parse("rancher/k3s:v1.20.4-k3s1"))
    .withNetwork(network)
    .withNetworkAliases("k3s");
String yaml = k3s.generateInternalKubeConfigYaml("k3s");
Defensive patterns

Strategy: validation

Validate before calling

if (!k3s.getNetworkAliases().contains(alias)) {
  throw new IllegalArgumentException(alias + " must be added via withNetworkAliases() before calling generateInternalKubeConfigYaml");
}

Try / catch

try {
  String yaml = k3s.generateInternalKubeConfigYaml(alias);
} catch (IllegalArgumentException e) {
  // fall back to default alias or log the available getNetworkAliases()
}

Prevention

When it happens

Trigger: Calling k3sContainer.generateInternalKubeConfigYaml("my-k3s") when 'my-k3s' was never added via withNetworkAliases(...) on a shared network, or the container was not started with any custom network aliases at all.

Common situations: Joining the k3s container to a Docker network but forgetting withNetworkAliases; misspelling the alias; calling generateInternalKubeConfigYaml from the host where the alias only resolves inside the network; creating the container via a definition/def API that drops the alias.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12). Data as JSON: /api/errors/6ef0c3b5d803052f. Report an issue: GitHub.

Appendix: source

Thrown at modules/k3s/src/main/java/org/testcontainers/k3s/K3sContainer.java:85

     */
    public String getKubeConfigYaml() {
        return kubeConfigYaml;
    }

    /**
     * Generate a kubernetes client configuration for use on a docker internal network. The kubeConfig can be used by
     * another docker container running in the same network as the k3s container. For access from the host, use
     * the {@link #getKubeConfigYaml()} method instead.
     *
     * @param networkAlias a valid network alias of the k3s container.
     * @return the kubeConfig yaml.
     */
    public String generateInternalKubeConfigYaml(String networkAlias) {
        if (this.getNetworkAliases().contains(networkAlias)) {
            String serverUrl = "https://" + networkAlias + ":" + KUBE_SECURE_PORT;
            return kubeConfigWithServerUrl(kubeConfigYaml, serverUrl);
        } else {
            throw new IllegalArgumentException(networkAlias + " is not a network alias for k3s container");
        }
    }

    @SneakyThrows
    private String kubeConfigWithServerUrl(String kubeConfigYaml, String serverUrl) {
        ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

        ObjectNode kubeConfigObjectNode = objectMapper.readValue(kubeConfigYaml, ObjectNode.class);

        JsonNode clusterNode = kubeConfigObjectNode.at("/clusters/0/cluster");
        if (!clusterNode.isObject()) {
            throw new IllegalStateException("'/clusters/0/cluster' expected to be an object");
        }
        ObjectNode clusterConfig = (ObjectNode) clusterNode;
        clusterConfig.replace("server", new TextNode(serverUrl));

        kubeConfigObjectNode.set("current-context", new TextNode("default"));

View on GitHub (pinned to 8e549514e3)