puppetlabs/puppet · error · ArgumentError

password must be specified if with_logon is used

Error message

password must be specified if with_logon is used

What it means

When Process.create is given :with_logon, it routes through CreateProcessWithLogonW, which requires credentials; create_process_with_logon raises ArgumentError('password must be specified if with_logon is used') unless :password is set. The check happens before the Win32 logon call, so no authentication attempt has been made and no Windows error code applies.

Source

Thrown at lib/puppet/util/windows/monkey_patches/process.rb:373

      startinfo[:lpTitle]         = si_hash[:title] if si_hash[:title]
      startinfo[:dwX]             = si_hash[:x] if si_hash[:x]
      startinfo[:dwY]             = si_hash[:y] if si_hash[:y]
      startinfo[:dwXSize]         = si_hash[:x_size] if si_hash[:x_size]
      startinfo[:dwYSize]         = si_hash[:y_size] if si_hash[:y_size]
      startinfo[:dwXCountChars]   = si_hash[:x_count_chars] if si_hash[:x_count_chars]
      startinfo[:dwYCountChars]   = si_hash[:y_count_chars] if si_hash[:y_count_chars]
      startinfo[:dwFillAttribute] = si_hash[:fill_attribute] if si_hash[:fill_attribute]
      startinfo[:dwFlags]         = si_hash[:startf_flags] if si_hash[:startf_flags]
      startinfo[:wShowWindow]     = si_hash[:sw_flags] if si_hash[:sw_flags]
      startinfo[:cbReserved2]     = 0
      startinfo[:hStdInput]       = si_hash[:stdin] if si_hash[:stdin]
      startinfo[:hStdOutput]      = si_hash[:stdout] if si_hash[:stdout]
      startinfo[:hStdError]       = si_hash[:stderr] if si_hash[:stderr]
      startinfo
    end

    def create_process_with_logon
      raise ArgumentError, 'password must be specified if with_logon is used' unless password

      hash[:creation_flags] |= CREATE_UNICODE_ENVIRONMENT

      bool = CreateProcessWithLogonW(
        logon,                  # User
        domain,                 # Domain
        password,               # Password
        LOGON_WITH_PROFILE,     # Logon flags
        app,                    # App name
        cmd,                    # Command line
        hash[:creation_flags],  # Creation flags
        env,                    # Environment
        cwd,                    # Working directory
        startinfo,              # Startup Info
        procinfo                # Process Info
      )

      raise SystemCallError.new('CreateProcessWithLogonW', FFI.errno) unless bool

View on GitHub (pinned to e227c27540)

Solutions

  1. Supply :password whenever :with_logon is set (pair it with :domain for non-local accounts)
  2. Validate secrets before the call: raise unless opts[:password] && !opts[:password].empty?
  3. Drop :with_logon entirely when inheriting the caller's credentials is acceptable
  4. Log which option was missing (never the credential value) to speed diagnosis

Example fix

// before
Process.create(command_line: 'backup.cmd', with_logon: 'svc_backup')  # no password

// after
Process.create(command_line: 'backup.cmd',
               with_logon: 'svc_backup', domain: 'CORP',
               password: fetch_secret('svc_backup'))
Defensive patterns

Strategy: validation

Validate before calling

if args[:with_logon]
  raise ArgumentError, 'password is required with with_logon' if args[:password].nil? || args[:password].empty?
end
Process.create(args)

Try / catch

begin
  info = Process.create(args)
rescue ArgumentError => e
  raise unless e.message.include?('password must be specified')
  raise 'with_logon requires credentials - fetch the secret before spawning'
end

Prevention

When it happens

Trigger: Process.create(command_line: 'batch.cmd', with_logon: 'svc_user') without :password; supplying :password => '' (empty string counts as present) vs nil; config where the password key is dropped by symbolization or YAML parsing of an empty value into nil.

Common situations: Running resources as a service account where the password comes from a secret store that returned nil; templates writing :with_logon but omitting :password on some branches; JWT/ENV-based credential loaders whose variable name casing mismatches (:Password vs :password is fine after to_s.to_sym, but 'pass' is not).

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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