puppetlabs/puppet · error · ArgumentError

Passwords cannot include ':'

Error message

Passwords cannot include ':'

What it means

The user type's `password` property takes a shadow-format password hash. /etc/shadow entries are colon-separated fields, so a value containing ':' would corrupt the stored entry; the validate (lib/puppet/type/user.rb:277) therefore raises ArgumentError for any String containing ':'. The property is sensitive and normally reports as [redacted].

Source

Thrown at lib/puppet/type/user.rb:277

            events:
            - !ruby/object:Puppet::Transaction::Event
              audited: false
              property: password
              previous_value: "[redacted]"
              desired_value: "[redacted]"
              historical_value:
              message: changed [redacted] to [redacted]
              name: :password_changed
              status: success
              time: 2017-05-17 16:06:02.934398293 -07:00
              redacted: true
              corrective_change: false
            corrective_change: false
        ```
        }

      validate do |value|
        raise ArgumentError, _("Passwords cannot include ':'") if value.is_a?(String) and value.include?(":")
      end

      sensitive true
    end

    newproperty(:password_min_age, :required_features => :manages_password_age) do
      desc "The minimum number of days a password must be used before it may be changed."

      munge do |value|
        case value
        when String
          Integer(value)
        else
          value
        end
      end

      validate do |value|

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass only the hash field itself (e.g. '$6$salt$hash...')
  2. Split salt/hash pairs in your generation pipeline before assigning
  3. Strip colons from the value in wrapper code and fail if any remain

Example fix

# before (whole shadow line pasted)
user { 'bob':
  ensure   => present,
  password => 'bob:$6$saltsalt$hashhashhash',
}

# after (hash field only)
user { 'bob':
  ensure   => present,
  password => '$6$saltsalt$hashhashhash',
}
Defensive patterns

Strategy: validation

Validate before calling

if $password != undef and $password =~ /:/ {
  fail('user password must be the bare hash; it cannot contain ":"')
}

Type guard

def valid_user_password?(pw)
  pw.is_a?(String) && !pw.include?(':')
end

Try / catch

begin
  Puppet::Type.type(:user).new(name: 'bob', password: 'bob:$6$s$hash')
rescue ArgumentError => e
  raise unless e.message.include?("Passwords cannot include ':'")
  # keep only the hash field and rebuild
end

Prevention

When it happens

Trigger: `user { 'bob': password => 'bob:$6$salt$hash' }` (whole shadow line pasted instead of just the hash field); generated secrets formatted as 'salt:hash'; stray trailing colon.

Common situations: Copy-pasting full lines from /etc/shadow or usermgmt exports; password-generator functions that emit 'salt:hash' pairs; YAML values carrying extra structure.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/ccf7660566c5fafd. Report an issue: GitHub.