puppetlabs/puppet · error · Puppet::Error
Could not parse JSON data for %{name} %{key}: %{detail}
Error message
Could not parse JSON data for %{name} %{key}: %{detail} What it means
After a successful binary read of the stored file, model.convert_from('json', text) raised - the stored bytes are not valid JSON for the model. Raised as Puppet::Error 'Could not parse JSON data for <indirection> <key>: <detail>', where detail is the parser's message (unexpected token, EOF, schema mismatch). Corruption here means the file was truncated, hand-edited, or written by an incompatible puppet version.
Source
Thrown at lib/puppet/indirector/json.rb:71
def data_dir
Puppet.run_mode.server? ? Puppet[:server_datadir] : Puppet[:client_datadir]
end
def load_json_from_file(file, key)
json = nil
begin
json = Puppet::FileSystem.read(file, :encoding => Encoding::BINARY)
rescue Errno::ENOENT
return nil
rescue => detail
raise Puppet::Error, _("Could not read JSON data for %{name} %{key}: %{detail}") % { name: indirection.name, key: key, detail: detail }, detail.backtrace
end
begin
from_json(json)
rescue => detail
raise Puppet::Error, _("Could not parse JSON data for %{name} %{key}: %{detail}") % { name: indirection.name, key: key, detail: detail }, detail.backtrace
end
end
def from_json(text)
model.convert_from('json', text.force_encoding(Encoding::UTF_8))
end
def to_json(object)
object.render('json')
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Identify the file from the key: <datadir>/<indirection>/<key>.json and validate it (jq . file, or ruby -rjson -e 'JSON.parse(File.read(ARGV[0]))' file).
- If the entry is regenerable (node cache, facts), delete it; Puppet recreates it on the next request.
- For non-regenerable stores, restore the file from backup.
- Fix the root cause: keep datadirs off full disks and never let external tools edit store files in place.
Example fix
# before: corrupted store entry # Could not parse JSON data for node node1.example.com: 859: unexpected token at '...' # after: drop the regenerable cache entry rm "$(puppet config print server_datadir)/node/node1.example.com.json" # the next request rebuilds it
Defensive patterns
Strategy: fallback
Validate before calling
file = store_path_for(key) if File.exist?(file) JSON.parse(Puppet::FileSystem.read(file)) rescue(throw :corrupt_entry) end
Try / catch
begin
data = Puppet::Node.indirection.find(key)
rescue Puppet::Error => e
if e.message.include?('Could not parse JSON data')
Puppet::Node.indirection.destroy(key) # ENOENT-safe removal
data = Puppet::Node.indirection.find(key) # rebuild the entry
else
raise
end
end Prevention
- Never let external tools edit store files in place.
- Monitor disk space where datadirs live.
- Alert on parse failures and auto-prune regenerable entries.
When it happens
Trigger: find/search hitting a corrupted store/cache file: disk-full truncation, a kill during a non-atomic write, manual edits to datadir files, or a downgrade opening files serialized by a newer puppet version.
Common situations: Crash loops during disk-pressure events; operators hand-editing stored json; version rollbacks after upgrades changed serialization; tools that rewrite datadir files in place.
Related errors
- #{path}: #{detail.message}
- Could not deserialize catalog from %{format}: %{detail}
- HTTP REST queries cannot handle values of type '%{klass}'
- Could not destroy %{json} %{request}: %{detail}
- invalid key
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/6f781b569bdd8561.
Report an issue: GitHub.