I'm running into the following error trying to allow some environment variables to pass through to the new environment when running sudo:

sudo: sorry, you are not allowed to preserve the environment

Some information that may be helpful to debug:

[deploy@worker1 ~]$ sudo -l
    Matching Defaults entries for deploy on this host:
    requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
    XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin, env_keep+="GIT_WORK_TREE GIT_DIR", !requiretty

User deploy may run the following commands on this host:
    (ALL) NOPASSWD: /usr/bin/git, (ALL) /etc/init.d/httpd*, (ALL) /sbin/service, (ALL) /usr/bin/make, (ALL) /bin/echo

My running example:

[deploy@worker1 ~]$ export GIT_DIR="/home/ashinn/testing"
[deploy@worker1 ~]$ sudo -E sh -c 'echo "$GIT_DIR"'
sudo: sorry, you are not allowed to preserve the environment

My sudoers.d file for this specific configuration:

Defaults:deploy         env_keep += "GIT_WORK_TREE GIT_DIR", !requiretty
deploy  ALL=(ALL)       NOPASSWD: /usr/bin/git, /etc/init.d/httpd*, /sbin/service, /usr/bin/make, /bin/echo

I've also tried adding !env_reset to the Defaults and it still fails with the same error. I feel like I may be missing something obvious and need a second set of eyes. What am I missing here?

  • 1
    I believe that approximately 93% of us understand the point of your question, but your example command isn't very good.  sudo (option(s)) echo $GIT_DIR, if it doesn't fail outright, will display the pre-sudo value of $GIT_DIR, because the shell expands the variable in the command line before sudo is even invoked.  Better tests are sudo printenv GIT_DIR or sudo env | grep GIT_DIR or sudo sh -c 'echo "$GIT_DIR"', where we're actually looking at the environment of the process that's running privileged. – G-Man Says 'Reinstate Monica' Nov 21 '15 at 7:00
  • See also this question on Stack Overflow. – Franklin Yu Aug 16 '18 at 0:22

You can use the SETENV "Tag" in your sudoers file, as in :

deploy  ALL=(ALL)       SETENV: /usr/bin/git, /etc/init.d/httpd*, /sbin/service, /usr/bin/make, /bin/echo

Or, to combine it with NOPASSWD:

deploy  ALL=(ALL)       NOPASSWD:SETENV: /usr/bin/git, /etc/init.d/httpd*, /sbin/service, /usr/bin/make, /bin/echo

Relevant excerpt from the sudoers man :


These tags override the value of the setenv option on a per-command basis. Note that if SETENV has been set for a command, the user may disable the env_reset option from the command line via the -E option. Additionally, environment variables set on the command line are not subject to the restrictions imposed by env_check, env_delete, or env_keep. As such, only trusted users should be allowed to set variables in this manner. If the command matched is ALL, the SETENV tag is implied for that command; this default may be overridden by use of the NOSETENV tag.


Don’t specify the -E option. Using -E you´re saying that all the environment variables for the user deploy should be preserved, not only GIT_DIR

Running sudo echo $GIT_DIR should work because you've added GIT_DIR to the env_keep list

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.