puppetlabs/puppet · error · Puppet::DataBinding::LookupError
Resolution type :# is illegal when accessing values using…
Error message
Resolution type :#{strategy} is illegal when accessing values using dotted keys. Offending key was '#{key}' What it means
This guard lives in the Hiera-3-compatibility shim of the global data provider: it only fires when lookup_invocation.hiera_xxx_call? is true (the legacy hiera()/hiera_hash()/hiera_array() functions), the requested key is a LookupKey with segments (a dotted key like 'app.db.host'), and the merge behavior is HashMergeStrategy (hiera_hash) or UniqueMergeStrategy (hiera_array). Dotted keys require the found value to be traversed per segment, which is incompatible with merging multiple found values, so it reproduces Hiera 3's familiar failure message.
Solutions
- Replace the legacy call with the modern lookup function: lookup('myapp.settings.override', Hash, {'merge' => 'hash'}) — dotted keys work with merge in lookup() because it resolves segments after merging.
- Or drop the merge behavior for that key: hiera('my.key.parts') / lookup without hash/array merge.
- Or rename the data key to use '::' instead of dots so it is not treated as a segmented (dotted) key.
Example fix
# before
$d = hiera_hash('myapp.settings.override')
# after
$d = lookup('myapp.settings.override', Hash, {'merge' => 'hash'}) Defensive patterns
Strategy: validation
Validate before calling
# Guard a legacy call path: never use hiera_hash/hiera_array with dotted keys
KEY = 'myapp.settings.override'
if KEY.include?('.')
$value = lookup(KEY, Hash, {'merge' => 'hash'}) # modern lookup handles dotted keys + merge
else
$value = hiera_hash(KEY)
end Try / catch
begin
$value = hiera_hash('myapp.settings.override')
rescue Puppet::DataBinding::LookupError => e
raise unless e.message.include?('illegal when accessing values using dotted keys')
$value = lookup('myapp.settings.override', Hash, {'merge' => 'hash'})
end Prevention
- Prefer lookup() over hiera_hash()/hiera_array() in all manifests — the legacy functions have dotted-key limits by design.
- Avoid dots in Hiera key names ('myapp::db_host' instead of 'myapp.db.host') to sidestep segment semantics entirely.
- Grep codebases for hiera_(hash|array)\(.*\. during Puppet 3→4 migrations.
When it happens
Trigger: Calling hiera_hash('myapp.settings.override') or hiera_array('my.list.items') — any dotted key — in a manifest or ERB template while data providers are in play; hiera() with an explicit hash/array merge and a dotted key also qualifies via the shim.
Common situations: Old Puppet 3-era code still using hiera_hash/hiera_array after moving to Puppet 4+/Hiera 5 data; keys deliberately named with dots (e.g. 'nginx.worker_processes') interacting with legacy function calls.
Related errors
- all keys must start with module name
- all patterns must match a key starting with module name
- Cannot use undef as a class name
- Command must be a String or Array
- Could not find data item
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/a77771326f2e7b29.
Report an issue: GitHub.
Appendix: source
Thrown at lib/puppet/pops/lookup/global_data_provider.rb:47
unless config.merge_strategy.is_a?(DefaultMergeStrategy)
if lookup_invocation.hiera_xxx_call? && merge.is_a?(HashMergeStrategy)
# Merge strategy defined in the hiera config only applies when the call stems from a hiera_hash call.
merge = config.merge_strategy
lookup_invocation.set_hiera_v3_merge_behavior
end
end
value = super(key, lookup_invocation, merge)
if lookup_invocation.hiera_xxx_call?
if merge.is_a?(HashMergeStrategy) || merge.is_a?(DeepMergeStrategy)
# hiera_hash calls should error when found values are not hashes
Types::TypeAsserter.assert_instance_of('value', Types::PHashType::DEFAULT, value)
end
if !key.segments.nil? && (merge.is_a?(HashMergeStrategy) || merge.is_a?(UniqueMergeStrategy))
strategy = merge.is_a?(HashMergeStrategy) ? 'hash' : 'array'
# Fail with old familiar message from Hiera 3
raise Puppet::DataBinding::LookupError, "Resolution type :#{strategy} is illegal when accessing values using dotted keys. Offending key was '#{key}'"
end
end
value
else
super
end
end
protected
def assert_config_version(config)
config.fail(Issues::HIERA_UNSUPPORTED_VERSION_IN_GLOBAL) if config.version == 4
config
end
# Return the root of the environment
#
# @param lookup_invocation [Invocation] The current lookup invocationView on GitHub (pinned to e227c27540)