{"record":{"id":"cb04615ce6b83cf0","repo":"puppetlabs/puppet","slug":"the-disable-per-environment-manifest-setting-is","errorCode":null,"errorMessage":"The 'disable_per_environment_manifest' setting is true, but the environment located at %{path_to_env} has a manifest setting in its environment.conf of '%{environment_conf}' which does not match the default_manifest setting '%{puppet_conf}'.","messagePattern":"The 'disable_per_environment_manifest' setting is true, but the environment located at %(.+?) has a manifest setting in its environment\\.conf of '%(.+?)' which does not match the default_manifest setting '%(.+?)'\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/puppet/settings/environment_conf.rb","lineNumber":74,"sourceCode":"  def manifest\n    puppet_conf_manifest = Pathname.new(Puppet.settings.value(:default_manifest))\n    disable_per_environment_manifest = Puppet.settings.value(:disable_per_environment_manifest)\n\n    fallback_manifest_directory =\n      if puppet_conf_manifest.absolute?\n        puppet_conf_manifest.to_s\n      else\n        File.join(@path_to_env, puppet_conf_manifest.to_s)\n      end\n\n    if disable_per_environment_manifest\n      environment_conf_manifest = absolute(raw_setting(:manifest))\n      if environment_conf_manifest && fallback_manifest_directory != environment_conf_manifest\n        # TRANSLATORS 'disable_per_environment_manifest' is a setting and 'environment.conf' is a file name and should not be translated\n        message = _(\"The 'disable_per_environment_manifest' setting is true, but the environment located at %{path_to_env} has a manifest setting in its environment.conf of '%{environment_conf}' which does not match the default_manifest setting '%{puppet_conf}'.\") %\n                  { path_to_env: @path_to_env, environment_conf: environment_conf_manifest, puppet_conf: puppet_conf_manifest }\n        message += ' ' + _(\"If this environment is expecting to find modules in '%{environment_conf}', they will not be available!\") % { environment_conf: environment_conf_manifest }\n        Puppet.err(message)\n      end\n      fallback_manifest_directory.to_s\n    else\n      get_setting(:manifest, fallback_manifest_directory) do |manifest|\n        absolute(manifest)\n      end\n    end\n  end\n\n  def environment_timeout\n    # gen env specific config or use the default value\n    get_setting(:environment_timeout, Puppet.settings.value(:environment_timeout)) do |ttl|\n      # munges the string form statically without really needed the settings system, only\n      # its ability to munge \"4s, 3m, 5d, and 'unlimited' into seconds - if already munged into\n      # numeric form, the TTLSetting handles that.\n      Puppet::Settings::TTLSetting.munge(ttl, 'environment_timeout')\n    end\n  end","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/settings/environment_conf.rb#L56-L92","documentation":"Logged by Puppet::Settings::EnvironmentConf when server-wide disable_per_environment_manifest is true but this environment's environment.conf declares a manifest path that, after absolutization, differs from the default_manifest setting. Per-environment manifests are forbidden in this mode, so Puppet falls back to the default manifest and warns that modules expected under the environment's manifest directory will not be available.","triggerScenarios":"Loading an environment whose environment.conf contains `manifest = ...` that does not resolve to the same absolute path as default_manifest, while puppet.conf sets disable_per_environment_manifest=true. raw_setting(:manifest) is absolutized against the env path and compared to the fallback directory.","commonSituations":"Hardening an existing Puppet installation (best practice pins all environments to one manifest) while control-repo environments still carry per-env manifest lines; moving default_manifest without updating environment.confs; boilerplate environment.conf templates that always set manifest.","solutions":["Remove the `manifest` line from the environment's environment.conf so the default applies","Or point default_manifest in puppet.conf at the same absolutized path the environment uses","Or disable disable_per_environment_manifest if per-environment manifests are intentional","Redeploy the corrected environment so the warning stops and the expected modules resolve"],"exampleFix":"# before\n# puppet.conf:      disable_per_environment_manifest = true\n# environment.conf: manifest = site/main.pp\n\n# after — environment.conf with no manifest override\nmodulepath = site:modules:$basemodulepath\n# (all environments now share the default_manifest)","handlingStrategy":"validation","validationCode":"if Puppet.settings.value(:disable_per_environment_manifest)\n  Dir.glob('/etc/puppetlabs/code/environments/*').each do |env_dir|\n    conf = File.join(env_dir, 'environment.conf')\n    next unless File.read(conf) =~ /^\\s*manifest\\s*=/\n    warn \"#{conf}: manifest setting is ignored while disable_per_environment_manifest is true\"\n  end\nend","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick one manifest policy: either pin default_manifest and forbid per-env manifest lines, or allow per-env manifests","Template environment.conf without a manifest line when hardening is enabled","Fail CI when deployed environment.conf files conflict with server-level settings"],"tags":["ruby","puppet","environment","configuration","manifest","settings"],"backgroundTag":"environment-config-conflict","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}