Start your free 14-day ContainIQ trial

Fixing CreateContainerError and CreateContainerConfigError

June 24, 2022

Some errors in Kubernetes can be a nightmare, and CreateContainerError and CreateContainerConfigError are two of them. This article will help you identify and resolve these errors.

Daniel Olaogun
Software Engineer

Kubernetes is an open source software for managing and deploying containerized applications across many servers. The smallest deployable unit of computing in Kubernetes is a pod, which contains one or more containers. A container is a packaged software application that includes all the necessary dependencies and binaries required to run the application.

When you deploy a pod in Kubernetes, Kubernetes creates the container from the image you specify in the pod object. However, there are situations where Kubernetes fails to create the container due to errors encountered while creating it. The errors include <terminal inline>CreateContainerError<terminal inline> and <terminal inline>CreateContainerConfigError<terminal inline>.

These errors can be tricky, so it’s important to understand their underlying causes to make it easier to avoid them. It’s also important to learn how to fix them, so you can resolve them when they occur. In this article, you’re going to learn more about these errors—how to identify them, what causes them, and how to fix them.

What are CreateContainerConfigError and CreateContainerError?

CreateContainerConfigError and CreateContainerError are errors that occur when a Kubernetes container is transitioning from a pending state to a running state. When a container enters a running state, it validates the deployment configuration to ensure that it is configured properly.

During this validation state, if a configuration such as the ConfigMap is missing, the CreateContainerConfigError comes up. CreateContainerError, on the other hand, occurs when your pod references a PersistentVolume that isn’t properly configured, or when Kubernetes tries to create a pod from the pod manifest file, and the container referenced in the pod’s manifest file has an empty or invalid ENTRYPOINT.

In the next sections of this article, you will be learning more about the causes of these errors, as well as how to resolve CreateContainerConfigError and CreateContainerError.

Identifying the CreateContainerConfigError

Let’s deploy a simple MySQL pod that relies on the following Kubernetes objects.

  • Secrets to store your username and password.
  • Configmap to store insensitive data.

Create a file named <terminal inline>mysql_pod.yaml<terminal inline> and paste the following content:


apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  containers:
    - image: mysql:5.6
      name: mysql
      env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        - name: MYSQL_DATABASE
          valueFrom:
            configMapKeyRef:
              name: mysql-config
              key: database_name
      ports:
        - containerPort: 3306
          name: mysql

In your terminal, run the code below.


kubectl create -f mysql_pod.yaml 

You will get the following response:


pod/mysql created

Get the pod you just created.


kubectl get pod mysql

You will receive a response with the status <terminal inline>CreateContainerConfigError<terminal inline>.

NAME READY STATUS RESTARTS AGE
mysql 0/1 CreateContainerConfigError 0 7s

Causes of CreateContainerConfigError and Solution

The main cause of <terminal inline>CreateContainerConfigError<terminal inline> is either a secret or ConfigMap that’s referenced in your pod, but doesn’t exist.

Continuing with the example project, run the following command:


kubectl describe pod mysql

You’ll receive a response describing the MySQL pod in detail. Scroll to the end of the response, where you’ll see an Events section. This is a list of events that have occurred in the process of creating the pod. You’ll see an event with the type <terminal inline>warning<terminal inline>, and the reason will be <terminal inline>Failed<terminal inline>. The message associated with that event indicates the cause of the <terminal inline>CreateContainerConfigError<terminal inline>. In this case, the message states that the secret wasn’t found, as seen below.

...

...

Events:

TYPE REASON AGE FROM MESSAGE
---- ------ --- ---- -------
Normal Scheduled 46s default-scheduler Successfully assigned default / mysql to minikube
Normal Pulled 14s (x5 over 44s) kubelet Container image "mysql:5.6" already present on machine
Warning Failed 14s (x5 over 44s) kubelet Error: secret "mysql-secret" not found

This indicates that Kubernetes wasn’t able to locate the secret named “mysql-secret”. To verify that, run the following.


kubectl get secret my-secret   

You will receive the following response:


Error from server (NotFound): secrets "my-secret" not found

As you can see from the response, the cause of the error is that you don’t have a secret object named <terminal inline>my-secret"<terminal inline> present in your cluster. When you were creating the <terminal inline>MySQL<terminal inline> pod manifest file, you referenced a secret and configMap in the env attribute without actually creating them.

Let’s create the secret object imperatively.


kubectl create secret generic mysql-secret --from-literal=password=supersecret

Then delete your MySQL pod and recreate it.


kubectl delete -f mysql_pod.yaml

kubectl create -f mysql_pod.yaml

After recreating the MySQL pod, run the command below to view the pod in detail.


kubectl describe pod mysql

This time around, you have the following error message, similar to the error you had previously.


Error: configmap "mysql-config" not found

Using the same approach used to fixing the missing secret, create a configMap for your pod.


kubectl create configmap mysql-config --from-literal=database_name=containiq_db

Delete and recreate the MySQL pod.


kubectl delete -f mysql_pod.yaml

kubectl create -f mysql_pod.yaml

View the newly created mysql pod.


kubectl get pod mysql

In the response, you will see that the status is no longer <terminal inline>CreateContainerConfigError<terminal inline>, but <terminal inline>Running<terminal inline>.

NAME READY STATUS RESTARTS AGE
mysql 1/1 Running 0 66s

Now that you know the causes and fixes for <terminal inline>CreateContainerConfigError<terminal inline>, you’ll look at <terminal inline>CreateContainerError<terminal inline>.

K8s Metrics, Logging, and Tracing
Monitor the health of your cluster and troubleshoot issues faster with pre-built dashboards that just work.
Start Free Trial Book a Demo

Identifying the CreateContainerError

To explain how to identify a <terminal inline>CreateContainerError<terminal inline>, let’s create a simple node app pod. Create a file name <terminal inline>nodeapp.yaml<terminal inline> in your working directory and paste the following content:


apiVersion: v1
kind: Pod
metadata:
  name: nodeapp
  labels:
    app: nodeapp
spec:
  containers:
    - image: tolustar/bad-node-app
      name: nodeapp
      ports:
        - containerPort: 8000

The image used to create the pod will be explained later on. Create the pod object by running the following:


kubectl apply -f nodeapp.yaml

The nodeapp is created. Run the following command to view the pod:


kubectl get pod nodeapp -o wide

It will return this response:

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nodeapp 0/1 CreateContainerError 0 18s 172.17.0.6 minikube <none> <none>

Let’s further identify the main cause of this error by running the following command:


kubectl describe pod nodeapp

Scroll to the end of the response, where you’ll see something similar to the response below.

...

Events:

TYPE REASON AGE FROM MESSAGE
---- ------ --- ---- -------
Normal Scheduled 55s default-scheduler Successfully assigned default / nodeapp to minikube
Normal Pulled 32s kubelet Successfully pulled image "tolustar/bad-node-app" in 2.925695647s
Warning Failed 17s (x3 over 51s) kubelet Error: Error response from daemon: No command specified

...

In the Events section, you will see an event that has the event type of warning, and the reason listed as failed. The message section states the cause of the error, which is “Error response from daemon: No command specified”.

Causes of CreateContainerError and Solution

In this section, you’ll be learning the cause of this error, as well as about other factors that can cause the <terminal inline>CreateContainerError<terminal inline>.

Command Not Available

In the <terminal inline>nodeapp<terminal inline> pod that you created, the image <terminal inline>tolustar/bad-node-app<terminal inline> was specified. The image is a node script that was built into an image using the following Dockerfile configuration.


FROM node:16.3.0-alpine
WORKDIR /usr/src/app
COPY package*.json ./

RUN npm install
COPY . .

EXPOSE 8080

ENTRYPOINT []

The above Dockerfile has an empty ENTRYPOINT. In Kubernetes, the command attribute is linked to the Docker ENTRYPOINT, which means you can override the container ENTRYPOINT by configuring the <terminal inline>command<terminal inline> attribute in your pod object. In the previous example, the <terminal inline>command<terminal inline> attribute wasn’t configured, and the Dockerfile used in building the bad-node-app has an empty ENTRYPOINT. This is what caused the <terminal inline>CreateContainerError<terminal inline> when you created the pod.

The first thing you need to investigate when you encounter <terminal inline>CreateContainerError<terminal inline> is to check that you have a valid ENTRYPOINT in the Dockerfile used to build your container image. However, if you don’t have access to the Dockerfile, you can configure your pod object by using a valid command in the <terminal inline>command<terminal inline> attribute of the object.

Delete the pod you created using <terminal inline>kubectl delete pod nodeapp<terminal inline>, and update your pod manifest file, <terminal inline>nodeapp.yaml<terminal inline>, to include a valid command attribute, as seen below.


apiVersion: v1
kind: Pod
metadata:
  name: nodeapp
  labels:
    app: nodeapp
spec:
  containers:
    - image: tolustar/bad-node-app
      name: nodeapp
      ports:
        - containerPort: 8000
      command: ["node", "index.js"]

Create the new nodeapp by running <terminal inline>kubectl create -f nodeapp.yaml<terminal inline>. Then run <terminal inline>kubectl get pod nodeapp -o wide<terminal inline>, and you will get a response that indicates your pod is running, as seen below.

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nodeapp 1/1 Running 0 13s 172.17.0.6 minikube <none> <none>

Issues Mounting a Volume

If your volume object is not well configured, it can cause <terminal inline>CreateContainerError<terminal inline> when it is mounted on a pod. To illustrate this, you’ll create a simple nginx app, with a PersistentVolume (PV) and PersistentVolumeClaim (PVC).

In your working directory, create a file called <terminal inline>nginx-storage.yaml<terminal inline> and paste in the following content.


# PersistentVolume

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "\\mnt\\data"
  storageClassName: standard
  persistentVolumeReclaimPolicy: Delete

---
# PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi
  storageClassName: standard

Then create the PV and PVC from the above manifest file.


kubectl create -f nginx-storage.yaml

Create another file named <terminal inline>nginx.yaml<terminal inline>, and paste in the following content:


apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
      volumeMounts:
        - name: web
          mountPath: /var/www/html
  volumes:
    - name: web
      persistentVolumeClaim:
        claimName: nginx-pvc

Create the nginx pod using the above manifest file.


kubectl create -f nginx.yaml  

View the nginx pod.


kubectl get pod nginx

You will see the following response.

NAME READY STATUS RESTARTS AGE
nginx 0/1 CreateContainerError 0 8s

When you use the <terminal inline>kubectl describe<terminal inline> command, it will give more details regarding the <terminal inline>CreateContainerError<terminal inline> status.


kubectl describe pod nginx

Towards the end of the response, you’ll see the following:

...

...

Events:

TYPE REASON AGE FROM MESSAGE
---- ------ --- ---- -------
Normal Scheduled 73s default-scheduler Successfully assigned default / nginx to minikube
Normal Pulled 70s kubelet Successfully pulled image "nginx" in 3.2106753s
Normal Pulled 66s kubelet Successfully pulled image "nginx" in 3.3019907s
Normal Pulled 51s kubelet Successfully pulled image "nginx" in 2.8763731s
Normal Pulled 37s kubelet Successfully pulled image "nginx" in 2.884672s
Normal Pulled 22s kubelet Successfully pulled image "nginx" in 2.9257591s
Normal Pulling 9s (x6 over 73s) kubelet Pulling image "nginx"
Warning Failed 5s (x6 over 70s) kubelet Error: Error response from daemon: create \mnt\data: "\\mnt\\data" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path

As you can see, there’s an issue with the configured path in the PersistentVolume that was created. Now, you’ll modify it and remove the invalid characters.

Delete the nginx pod, PV, and PVC.


kubectl delete -f nginx.yamlkubectl delete -f nginx-storage.yaml

Edit the <terminal inline>nginx-storage.yaml<terminal inline> file, changing line 13 from <terminal inline>path: "\\mnt\\data" to path: "/mnt/data"<terminal inline>. Save the file.

Recreate the PV, PVC, and pod from the <terminal inline>nginx-storage<terminal inline> and <terminal inline>nginx<terminal inline> manifest files.


kubectl create -f nginx-storage.yaml

kubectl create -f nginx.yaml

View the status of the pod again.


kubectl get pod nginx

You now have a running pod.

NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 47s

Container Runtime Not Cleaning Up Old Containers

Another time you might encounter <terminal inline>CreateContainerError<terminal inline> is when a node’s container runtime doesn’t clean up old containers. If this has happened, when you try to create a new pod object using the same container name as one of the old containers, Kubernetes won’t be able to create the pod, and you’ll get the <terminal inline>CreateContainerError<terminal inline>. If you check the pod description using the <terminal inline>kubectl describe pod [POD_NAME]<terminal inline>, the event attribute will have a message similar to this:


The container name "/nodeapp_da3b72ec5abc" is already in use by container "42cdf3fe5007b75a4f4889b99c166233bb323f7293cf1188edf1ca90d812d2d3". You have to remove (or rename) that container to be able to reuse that name.

To resolve this error, you have to reinstall the node’s container runtime and re-register the affected node, where Kubernetes is trying to assign the container’s pod.

Final Thoughts

Troubleshooting <terminal inline>CreateContainerError<terminal inline> and <terminal inline>CreateContainerConfigError<terminal inline> can be frustrating if you don’t understand the underlying cause of these errors. Now that you have a solid understanding of the causes of the errors though, you can confidently avoid them if they appear—or, better yet, avoid them altogether.

Monitoring events and logs generated in your cluster is very important for the health and performance of your cluster. A good monitoring tool will offer you insights that will help you improve the performance of your cluster, and will help you identify, debug, and resolve issues like the ones covered in this tutorial. ContainIQ’s K8s native platform offers you an intuitive, visually friendly dashboard from which you can monitor your cluster’s log, events, and core metrics. Included, you can use ContainIQ to track and alert on both CreateContainerError and CreateContainerConfigError in real-tme.

It works with a one-line install, so it’s quick and easy to get started. Sign up for an account, or book a demo to see ContainIQ in action and learn more about how it can help you keep your cluster healthy and bug free.

Start your free 14-day ContainIQ trial
Start Free TrialBook a Demo
No card required
Daniel Olaogun
Software Engineer

Daniel is a Software Engineer with 5 years of experience building software solutions in a variety of fields. Today, he works as the Lead Software Engineer at Whitesmith. Daniel has a Bachelor’s Degree in Computer Science from the University of Lagos.

READ MORE