Some images do not return a valid Config object causing an AttributeError: 'NoneType' object has no attribute 'get'
SUMMARY
Starting a running container using community.docker.docker_container causes this error:
fatal: [docker1.vm.scz-vm.net]: FAILED! => changed=false
msg: 'Task failed: Module failed: ''NoneType'' object has no attribute ''get'''
ISSUE TYPE
- Bug Report
COMPONENT NAME
community.docker.docker_container:
ANSIBLE VERSION
ansible [core 2.19.0]
config file = /home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg
configured module search path = ['/home/martin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /home/martin/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.13.7 (main, Aug 20 2025, 22:17:40) [GCC 15.2.0] (/usr/bin/python3)
jinja version = 3.1.6
pyyaml version = 6.0.2 (with libyaml v0.2.5)
COLLECTION VERSION
# /home/martin/.ansible/collections/ansible_collections
Collection Version
---------------- -------
community.docker 3.13.10
# /usr/lib/python3/dist-packages/ansible_collections
Collection Version
---------------- -------
community.docker 4.6.1
CONFIGURATION
CACHE_PLUGIN(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = yaml
CACHE_PLUGIN_CONNECTION(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = .ansible/facts
CALLBACKS_ENABLED(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = ['profile_tasks']
CONFIG_FILE() = /home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg
DEFAULT_BECOME(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = True
DEFAULT_FORKS(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = 25
DEFAULT_GATHERING(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = smart
DEFAULT_LOAD_CALLBACK_PLUGINS(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = True
DEFAULT_STDOUT_CALLBACK(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = yaml
DEFAULT_UNDEFINED_VAR_BEHAVIOR(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = True
DEPRECATION_WARNINGS(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = True
HOST_KEY_CHECKING(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = False
INTERPRETER_PYTHON(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = /usr/bin/python3
MAX_FILE_SIZE_FOR_DIFF(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = 1044480
OS / ENVIRONMENT
Linux Ubuntu 25.10
STEPS TO REPRODUCE
- Have community.docker.docker_container task to start a container
- Run playbook
- Experience crash
- name: "Create the pyFF container"
community.docker.docker_container:
name: "{{ containers.pyff }}"
image: "{{ images.pyff }}"
restart_policy: "always"
state: "started"
pull: true
init: true
env:
USER: "{{ metadata_user_uid | string }}"
GROUP: "{{ metadata_group_gid | string }}"
mounts:
- source: "{{ metadata_basedir }}/web"
target: "/opt/pyff/web"
type: "bind"
- source: "{{ metadata_basedir }}/feeds"
target: "/opt/pyff/feeds"
type: "bind"
read_only: true
- source: "{{ metadata_basedir }}/src"
target: "/opt/pyff/src"
type: "bind"
read_only: true
- source: "{{ metadata_basedir }}/certs"
target: "/opt/pyff/certs"
type: "bind"
read_only: true
- source: "{{ metadata_basedir }}/xslt"
target: "/opt/pyff/xslt"
type: "bind"
read_only: true
healthcheck:
test:
- "CMD"
- "bash"
- "-c"
- "[[ $(($(date +%s)-$(date -r /opt/pyff/web/idps.xml +%s))) -lt 400 ]]"
interval: "10s"
timeout: "5s"
retries: 3
start_period: "5s"
EXPECTED RESULTS
Started container
ACTUAL RESULTS
[ERROR]: Task failed: Module failed: 'NoneType' object has no attribute 'get'
Origin: /home/martin/Projects/SURF/SRAM/SRAM-deploy/roles/docker_metadata/tasks/pyff.yml:66:3
64 notify: "Restart the pyFF container"
65
66 - name: "Create the pyFF container"
^ column 3
fatal: [docker1.vm.scz-vm.net]: FAILED! => changed=false
msg: 'Task failed: Module failed: ''NoneType'' object has no attribute ''get'''
The problem is in line 663 of module_container/docker_api.py:
if image and image['Config'].get('Env'):
In docker 29, the image object api contains null for Config, so it can't get 'Env':
# docker inspect ghcr.io/surfscz/sram-pyff:main
[
{
"Id": "sha256:5afcd4f96dc2970611c8446e11494c65bb36e2f5790be19a76033b3152de6bcf",
"RepoTags": [
"ghcr.io/surfscz/sram-pyff:main"
],
"RepoDigests": [
"ghcr.io/surfscz/sram-pyff@sha256:5afcd4f96dc2970611c8446e11494c65bb36e2f5790be19a76033b3152de6bcf"
],
"Config": null,
"Architecture": "",
"Os": "",
"Size": 96404588,
"RootFS": {},
"Metadata": {
"LastTagTime": "2025-11-20T07:10:44.519152963Z"
},
"Descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:5afcd4f96dc2970611c8446e11494c65bb36e2f5790be19a76033b3152de6bcf",
"size": 3232
}
}
]
After changing 663 to this:
if image and image.get('Config') is not None:
if image['Config'].get('Env'):
and 986 to this:
if image and image.get('Config') is not None:
and 1006 to:
if image and image.get('Config') is not None:
and 1210 to:
if image and image.get('Config') is not None:
.... everything works as expected.
This seems to be a bug in Docker 29 when migrating from earlier versions, see #1194. Try to re-pull the image.
(Simply ignoring this in the code is the wrong approach, your containers likely end up in a wrong state since some of their configuration is missing.)
No, removing the image doesn't help. docker_container will always fail the second run and the image inspect is again incomplete. What's interesting is that docker says the image is the only one not "In Use" by any container (signified by the U behind the image name), which simply isn't true?
Here's a Docker bug report for this issue: https://github.com/moby/moby/issues/51566
(According to the API docs: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect the Config field never should be null.)
@mrvanes I am trying this:
- removing
containerd.io - removing
/var/lib/containerd - reinstalling
containerd.io
Note that I am using the containerd backing store to ensure I can build multi-platform images:
❯ cat --plain /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"tag": "{{.Name}}/{{.ImageName}}"
},
"ipv6": true,
"fixed-cidr-v6": "<NOMNOMNOM>",
"features": {
"containerd-snapshotter": true
}
}
Ignore above, still fails.
This feels weirdly relevant: https://github.com/moby/moby/issues/51532
Thx for your time and apologies for assuming this was a docker_container issue. I agree https://github.com/moby/moby/issues/51566 looks like the most likely candidate for my problems!
No worries. It's far from obvious that this isn't an issue with the module. I first thought that I'd have to fix it, but then I noticed that Config being null is just wrong and means that something is broken with Docker. Making the module accept that will likely screw up your deployments, since (potentially) important image-specific configuration is not used.
We fixed it for now by sticking the "docker host" container to docker 28.
https://github.com/moby/moby/issues/51566#issuecomment-3601718061
Once https://github.com/moby/moby/pull/51629 is released I'll bump docker-ce and report back here.
29.1.2 is out with that fix: https://github.com/moby/moby/releases/tag/docker-v29.1.2
29.1.2 is out with that fix: https://github.com/moby/moby/releases/tag/docker-v29.1.2
Let me run a test. I'll report back. If I don't report back, it means my home DNS is down.
Still works here. I'll let it run for a day or 2 and report back.
With "still works here", you mean the problem is still there, or that it seems to be gone and it's working as before 29.0.0?
With "still works here", you mean the problem is still there, or that it seems to be gone and it's working as before 29.0.0?
Sorry, I should've been more explicit.
I installed 29.1.2 and the bug in this issue (#1206) is gone.
And last update from me: One of the container that always was giving me issues (see https://github.com/ansible-collections/community.docker/issues/1194) updated this morning, and the ansible scripts ran without any problems.
@kristof-mattei that's great to hear!