canonical / canonical/cloud-init
[bug] cloud-init-local.service crashes with AttributeError on failed jinja template render
- Dominant language
- Python
- Stars
- 3.8k
- Forks
- 1.1k
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 18
Description
# Bug report
Trying to render a jinja template file with nested instance-data attributes that isn't provided by the active DataSource fails the init stage and prevent cloud-init from starting up.
`render_jinja_payload_from_file()` returns a `None` value when it can't render a template that isn't syntax related. `util.read_conf()` doesn't happen to have any checks for this `None` return and instead passes it to the `load_yaml()` function which tries to run `decode_binary(None)` and raises the AttributeError.
Tracing back. This seems this was removed in #5350 due to mypy warnings as the render functions had no return annotations.
## Steps to reproduce the problem
Have a 'None' data source and inspect `cloud-init-main.service`
## Environment details
- Cloud-init version: 26.1 (Reproduced on main branch as well)
- Operating System Distribution: Any fedora-derived distro (But running a custom Amazon Linux KVM image here)
- Cloud provider, platform or installer type: None
1. Create /etc/cloud/cloud.cfg.d/10_test.cfg:
```
## template: jinja
#cloud-config
write_files:
- content: |
{{ ds.meta_data.placement.region | default("fallback") }}
path: /tmp/out
```
2. Boot on a platform with NoCloud/None datasource where `ds.meta_data.placement` isn't available. I thought the `default()` would help but it didn't get triggered.
3. Check the logs.
## cloud-init logs
```
2026-08-16 12:32:28,652 - jinja_template.py[WARNING]: Ignoring jinja template for /etc/cloud/cloud.cfg.d/10_test.cfg: 'dict object' has no attribute 'placement'
2026-08-16 12:32:28,652 - main.py[ERROR]: failed stage init
Traceback (most recent call last):
File "/usr/lib/python3.14/site-packages/cloudinit/cmd/main.py", line 967, in status_wrapper
ret = functor(name, args)
File "/usr/lib/python3.14/site-packages/cloudinit/cmd/main.py", line 582, in main_init
iid = init.instancify()
File "/usr/lib/python3.14/site-packages/cloudinit/stages.py", line 568, in instancify
return self._reflect_cur_instance()
~~~~~~~~~~~~~~~~~~~~~~~~~~^^
...
File "/usr/lib/python3.14/site-packages/cloudinit/util.py", line 1142, in read_conf_with_confd
confd_cfg = read_conf_d(confd, instance_data_file=instance_data_file)
File "/usr/lib/python3.14/site-packages/cloudinit/util.py", line 1086, in read_conf_d
read_conf(
~~~~~~~~~^
path,
^^^^^
instance_data_file=instance_data_file,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/usr/lib/python3.14/site-packages/cloudinit/util.py", line 359, in read_conf
return load_yaml(config_file, default={}) # pyright: ignore
File "/usr/lib/python3.14/site-packages/cloudinit/util.py", line 976, in load_yaml
blob = decode_binary(blob)
File "/usr/lib/python3.14/site-packages/cloudinit/util.py", line 143, in decode_binary
return blob if isinstance(blob, str) else blob.decode(encoding=encoding)
^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'decode'
failed run of stage init
------------------------------------------------------------
...
Aug 16 12:32:28 localhost cloud-init[3025]: 2026-08-16 12:32:28,773 - socket.py[CRITICAL]: AttributeError("'NoneType' object has no attribute 'decode'") in
Aug 16 12:32:28 localhost systemd[1]: cloud-init-main.service: Main process exited, code=exited, status=1/FAILURE
Aug 16 12:32:28 localhost systemd[1]: cloud-init-main.service: Failed with result 'exit-code'.
```
Contributor guide
Research direction
Start in cloudinit/util.py at read_conf(), load_yaml(), and decode_binary(), then inspect render_jinja_payload_from_file() in jinja_template.py. Reproduce the failure with the cloud.cfg.d example and review the traceback. Done means a failed non-syntax Jinja render no longer reaches decode_binary(None) or crashes cloud-init during init.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100