puppetlabs/puppet · error · ArgumentError
The given string in encoding '%{enc}' is invalid. Cannot cre
Error message
The given string in encoding '%{enc}' is invalid. Cannot create a Binary UTF-8 representation What it means
PBinaryType::Binary.from_string builds a Binary by validating the input string in its declared encoding, transcoding to UTF-8, then forcing ASCII-8BIT. If the string contains byte sequences that are invalid in its own encoding, the validity assertion fails with this ArgumentError because no lossless conversion exists.
Source
Thrown at lib/puppet/pops/types/p_binary_type.rb:77
end
# Creates a new Binary from a String containing text/binary in its given encoding. If the string's encoding
# is not already UTF-8, the string is first transcoded to UTF-8.
# This means that this binary will have the UTF-8 byte representation of the original string.
# For this to be valid, the encoding used in the given string must be valid.
# The validity of the given string is therefore asserted.
#
# The given string will be frozen as a side effect if it is in ASCII-8BIT encoding. If this is not
# wanted, a copy should be given to this method.
#
# @param [String] A string with valid content in its given encoding
# @return [Puppet::Pops::Types::PBinaryType::Binary] with the UTF-8 representation of the UTF-8 transcoded string
# @api public
#
def self.from_string(encoded_string)
enc = encoded_string.encoding.name
unless encoded_string.valid_encoding?
raise ArgumentError, _("The given string in encoding '%{enc}' is invalid. Cannot create a Binary UTF-8 representation") % { enc: enc }
end
# Convert to UTF-8 (if not already UTF-8), and then to binary
encoded_string = (enc == "UTF-8") ? encoded_string.dup : encoded_string.encode('UTF-8')
encoded_string.force_encoding("ASCII-8BIT")
new(encoded_string)
end
# Creates a new Binary from a String containing raw binary data of unknown encoding. If the string's encoding
# is not already ASCII-8BIT, a copy of the string is forced to ASCII-8BIT (that is Ruby's "binary" format).
# This means that this binary will have the exact same content, but the string will considered
# to hold a sequence of bytes in the range 0 to 255.
#
# @param [String] A string with binary data
# @api private
#
def initialize(bin)
@binary_buffer = (bin.encoding.name == "ASCII-8BIT" ? bin : bin.b).freezeView on GitHub (pinned to e227c27540)
Solutions
- If the data is raw bytes of unknown/untrusted encoding, use Binary.from_binary_string(raw.dup) instead — it performs no transcoding.
- Fix the upstream read: open files/sockets with 'rb' / set binmode so bytes keep ASCII-8BIT encoding from the start.
- Only if losing bad bytes is acceptable, clean the string first: str.scrub!("?") or re-encode from the true source encoding.
Example fix
# before bin = Puppet::Pops::Types::PBinaryType::Binary.from_string(raw_bytes) # after bin = Puppet::Pops::Types::PBinaryType::Binary.from_binary_string(raw_bytes.dup)
Defensive patterns
Strategy: validation
Validate before calling
# Ruby — choose the right constructor up front if raw.encoding == Encoding::ASCII_8BIT || !raw.valid_encoding? bin = Puppet::Pops::Types::PBinaryType::Binary.from_binary_string(raw.dup) else bin = Puppet::Pops::Types::PBinaryType::Binary.from_string(raw) end
Type guard
def transcodable_string?(s) s.is_a?(String) && s.valid_encoding? end
Try / catch
begin Puppet::Pops::Types::PBinaryType::Binary.from_string(s) rescue ArgumentError Puppet::Pops::Types::PBinaryType::Binary.from_binary_string(s.dup) # treat as raw bytes end
Prevention
- Open files and sockets in binary mode when the payload is binary; never force_encoding to UTF-8 without transcoding.
- Use from_binary_string for raw byte payloads; reserve from_string for valid encoded text.
When it happens
Trigger: Ruby: Puppet::Pops::Types::PBinaryType::Binary.from_string(str) where !str.valid_encoding?. Puppet DSL: Binary('...') with an argument carrying invalid bytes for its encoding — typically data that was force_encoding'd to UTF-8 upstream without being transcoded.
Common situations: Reading raw bytes from a socket/file opened without binary mode and routing them through Binary(); database or JSON strings already corrupted by a prior force_encoding; concatenating UTF-8 and binary fragments into one string.
Related errors
- Illegal format '#{actual}' specified for value of Binary typ
- Data Type Load Error for type '%{type_name}': %{message}
- a data type must have an interface
- a data type can only have one interface
- a data type can only have one implementation
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/9577efddfa6c2223.
Report an issue: GitHub.