diff --git a/libraries/ghc-internal/src/GHC/Internal/System/Environment.hs b/libraries/ghc-internal/src/GHC/Internal/System/Environment.hs
index c8f5baefc08cd45b755e5577553c2d181d225a42..fa89b0d3327e4782c4ebe6def485b22b3b266614 100644
--- a/libraries/ghc-internal/src/GHC/Internal/System/Environment.hs
+++ b/libraries/ghc-internal/src/GHC/Internal/System/Environment.hs
@@ -225,6 +225,13 @@ ioe_missingEnvVar name = ioException (IOError Nothing NoSuchThing "getEnv"
 -- Throws `Control.Exception.IOException` if @name@ is the empty string or
 -- contains an equals sign.
 --
+-- Beware that this function must not be executed concurrently
+-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread
+-- reading environment variables at the same time with another one modifying them
+-- can result in a segfault, see
+-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html)
+-- for discussion.
+--
 -- @since base-4.7.0.0
 setEnv :: String -> String -> IO ()
 setEnv key_ value_
@@ -269,6 +276,13 @@ foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt
 -- Throws `Control.Exception.IOException` if @name@ is the empty string or
 -- contains an equals sign.
 --
+-- Beware that this function must not be executed concurrently
+-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread
+-- reading environment variables at the same time with another one modifying them
+-- can result in a segfault, see
+-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html)
+-- for discussion.
+--
 -- @since base-4.7.0.0
 unsetEnv :: String -> IO ()
 #if defined(mingw32_HOST_OS)
diff --git a/libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc b/libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc
index e577456ed577d99ccfa3848d9ffe38c5b4b2dcb8..4c5360220ae86d491d6fc5f42399fb552eb3bc38 100644
--- a/libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc
+++ b/libraries/ghc-internal/src/GHC/Internal/System/Environment/Blank.hsc
@@ -109,6 +109,13 @@ getEnvDefault name fallback = fromMaybe fallback <$> getEnv name
 -- | Like 'GHC.Internal.System.Environment.setEnv', but allows blank environment values
 -- and mimics the function signature of 'System.Posix.Env.setEnv' from the
 -- @unix@ package.
+--
+-- Beware that this function must not be executed concurrently
+-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread
+-- reading environment variables at the same time with another one modifying them
+-- can result in a segfault, see
+-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html)
+-- for discussion.
 setEnv ::
   String {- ^ variable name  -} ->
   String {- ^ variable value -} ->
@@ -151,6 +158,13 @@ foreign import ccall unsafe "setenv"
 -- | Like 'GHC.Internal.System.Environment.unsetEnv', but allows for the removal of
 -- blank environment variables. May throw an exception if the underlying
 -- platform doesn't support unsetting of environment variables.
+--
+-- Beware that this function must not be executed concurrently
+-- with 'getEnv', 'lookupEnv', 'getEnvironment' and such. One thread
+-- reading environment variables at the same time with another one modifying them
+-- can result in a segfault, see
+-- [Setenv is not Thread Safe](https://www.evanjones.ca/setenv-is-not-thread-safe.html)
+-- for discussion.
 unsetEnv :: String -> IO ()
 #if defined(mingw32_HOST_OS)
 unsetEnv key = withCWString key $ \k -> do