puma/puma · error · ArgumentError

workers must be an Integer or :auto

Error message

workers must be an Integer or :auto

What it means

ArgumentError from Puma::Configuration#parse_workers (lib/puma/configuration.rb:450): worker counts must be an Integer, an integer-like string, or 'auto'/:auto (which resolves to Concurrent.available_processor_count). Anything Integer() cannot coerce — '2.5', 'two', ' ', or a wrong-typed value — is re-raised with this message. It flows from the workers DSL (lib/puma/dsl.rb:739) and from the WEB_CONCURRENCY environment variable read at lib/puma/configuration.rb:250.

Source

Thrown at lib/puma/configuration.rb:450

    def require_processor_counter
      require 'concurrent/utility/processor_counter'
    rescue LoadError
      warn <<~MESSAGE
        WEB_CONCURRENCY=auto or workers(:auto) requires the "concurrent-ruby" gem to be installed.
        Please add "concurrent-ruby" to your Gemfile.
      MESSAGE
      raise
    end

    def parse_workers(value)
      if value == :auto || value == 'auto'
        require_processor_counter
        Integer(::Concurrent.available_processor_count)
      else
        Integer(value)
      end
    rescue ArgumentError, TypeError
      raise ArgumentError, "workers must be an Integer or :auto"
    end

    # Load and use the normal Rack builder if we can, otherwise
    # fallback to our minimal version.
    def rack_builder
      # Load bundler now if we can so that we can pickup rack from
      # a Gemfile
      if @puma_bundler_pruned
        begin
          require 'bundler/setup'
        rescue LoadError
        end
      end

      begin
        require 'rack'
        require 'rack/builder'
        ::Rack::Builder

View on GitHub (pinned to b8341dc946)

Solutions

  1. Set WEB_CONCURRENCY to a plain integer string ('2') or 'auto'
  2. In config/puma.rb use workers Integer(workers_count) or workers :auto — never a float or free text
  3. Inspect the actual value at deploy time: p "WEB_CONCURRENCY=#{ENV['WEB_CONCURRENCY'].inspect}" before starting Puma
  4. Fix the source (docker-compose env, .env, CI variable) rather than overriding in the config file

Example fix

# docker-compose.yml — before
environment:
  - WEB_CONCURRENCY=two

# after
environment:
  - WEB_CONCURRENCY=2
Defensive patterns

Strategy: validation

Validate before calling

# deploy-time guard before booting Puma
if (w = ENV['WEB_CONCURRENCY'])
  raise ArgumentError, "WEB_CONCURRENCY must be an integer or 'auto', got #{w.inspect}" unless w.match?(/\A\d+\z|\Aauto\z/)
end

Type guard

def valid_workers?(v) = v.nil? || v == :auto || v == 'auto' || (Integer(v) rescue false)

Try / catch

# wrapper starting Puma with a clear failure message
begin
  require 'puma/launcher' # or shell out to `bundle exec puma`
rescue ArgumentError => e
  abort "puma config/ENV error: #{e.message} (check WEB_CONCURRENCY=#{ENV['WEB_CONCURRENCY'].inspect})"
end

Prevention

When it happens

Trigger: workers "2.5" or workers :four in config/puma.rb; ENV['WEB_CONCURRENCY'] set to 'two', '2.5', or a stray character via .env, docker-compose, or CI secrets. Note nil is legal for the DSL (means 0), and strings like '2' are fine because Integer('2') works; only 'auto' is special-cased.

Common situations: Typo'd WEB_CONCURRENCY in deployment tooling (Capistrano, Kamal, Heroku config vars); .env files with trailing characters or units ('2 workers'); configs passing a Float; scripts exporting variables with quotes/whitespace corruption.

Related errors


AI-assisted analysis of puma/puma@b8341dc946 (2026-08-21). Data as JSON: /api/errors/68be2eeffb2a5411. Report an issue: GitHub.