# Security error with the new 0.161.0 security for PostCSS

**URL:** <https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186>\
**Category:** support\
**Tags:** security\
**Created:** [May 21, 2026, 2:39pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186 "2026-05-21T14:39:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![divinerites](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/divinerites/32/12625_2.png) [@divinerites](https://discourse.gohugo.io/u/divinerites)\
**Post date:** [May 21, 2026, 2:39pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/1 "2026-05-21T14:39:28Z")

</div>

Upgrading with 0.161.1 i get an error obviously related to new security in 0.161.0.  
But despite reading and trying to understand the advice in the release doc, I just fail to understand what i have to do (in security.node permission I guess) 🫣

Any hint or advice welcome.

PS : hugo server doesn’t show this error, confirming relation with postcss process

```auto
panic: POSTCSS: failed to transform "/css/style.css" (text/css): Error: Access to this API has been restricted. Use --allow-fs-read to manage permissions.
            at Object.existsSync (node:fs:286:18)
            at isFile (/Users/didiergeorgieff/Documents/Git/osteo-timer/node_modules/browserslist/node.js:38:19)
            at /Users/didiergeorgieff/Documents/Git/osteo-timer/node_modules/browserslist/node.js:317:11
            at eachParent (/Users/didiergeorgieff/Documents/Git/osteo-timer/node_modules/browserslist/node.js:49:18)
            at Object.findConfig (/Users/didiergeorgieff/Documents/Git/osteo-timer/node_modules/browserslist/node.js:305:20)
            at browserslist.loadConfig (/Users/didiergeorgieff/Documents/Git/osteo-timer/node_modules/browserslist/node.js:223:37)
            at browserslist (/Users/didiergeorgieff/Documents/Git/osteo-timer/node_modules/browserslist/index.js:411:31)
            at Browsers.parse (/Users/didiergeorgieff/Documents/Git/osteo-timer/node_modules/autoprefixer/lib/browsers.js:54:12)
            at new Browsers (/Users/didiergeorgieff/Documents/Git/osteo-timer/node_modules/autoprefixer/lib/browsers.js:42:26)
            at loadPrefixes (/Users/didiergeorgieff/Documents/Git/osteo-timer/node_modules/autoprefixer/lib/autoprefixer.js:113:20) {
          code: 'ERR_ACCESS_DENIED',
          permission: 'FileSystemRead',
          resource: '/Users/didiergeorgieff/Documents/Git/package.json'
        }

```

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [May 21, 2026, 2:50pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/2 "2026-05-21T14:50:59Z")

</div>

Do you have a “security” section in your project configuration?  
Or in your environment variables?

Check by running:

```plaintext
hugo config | grep security -A5

```

---

<div class="post-metadata">

**Author:** ![divinerites](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/divinerites/32/12625_2.png) [@divinerites](https://discourse.gohugo.io/u/divinerites)\
**Post date:** [May 21, 2026, 3:11pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/3 "2026-05-21T15:11:57Z")

</div>

No. I had no security section.

I am trying to add one but i still get new errors (all security related)

````.browserslistrc  
0.5%  
last 2 versions  
not dead

````

> ################################ SECURITY \> v0.161.0 ########################
> 
> [security]
> 
> enableInlineShortcodes = true
> 
> [security.exec]
> 
> allow = [
> 
> “^(dart-)?sass(-embedded)?$”,
> 
> “^go$”,
> 
> “^git$”,
> 
> “^npx$”,
> 
> “^node$”,
> 
> “^postcss$”,
> 
> “^tailwindcss$”
> 
> ]
> 
> osEnv = [
> 
> “(?i)^((HTTPS?|NO)\_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\\w+|(XDG\_CONFIG\_)?HOME|USERPROFILE|SSH\_AUTH\_SOCK|DISPLAY|LANG|SYSTEMDRIVE|PROGRAMDATA)$”
> 
> ]
> 
> [security.funcs]
> 
> getenv = [“^HUGO\_”, “^CI$”]
> 
> [security.http]
> 
> methods = [“(?i)GET|POST”]
> 
> urls = [“.\*”]

---

<div class="post-metadata">

**Author:** ![divinerites](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/divinerites/32/12625_2.png) [@divinerites](https://discourse.gohugo.io/u/divinerites)\
**Post date:** [May 21, 2026, 3:17pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/4 "2026-05-21T15:17:35Z")

</div>

And I finally just got it working with this command (and the 2 modified files upper):

```auto
NODE_OPTIONS="--permission --allow-fs-read=/Users/didiergeorgieff/Documents/Git/osteo-timer --allow-fs-read=/Users/didiergeorgieff/Documents/Git" hugo server

```

But I am wondering if it is a dirty hack of will be our future ?  
ANd also i hve to figure how to industrilize it for Netlify.

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [May 21, 2026, 3:23pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/5 "2026-05-21T15:23:50Z")

</div>

I don’t understand the formatting of your repsonse. For example, when I run `hugo config | grep security -A5` I get this:

```plaintext
[security]
  [security.exec]
    allow = ['^(dart-)?sass(-embedded)?$', '^go$', '^git$', '^node$', '^postcss$', '^tailwindcss$']
    osenv = ['(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\w+|(XDG_CONFIG_)?HOME|USERPROFILE|SSH_AUTH_SOCK|DISPLAY|LANG|SYSTEMDRIVE|PROGRAMDATA)$']

  [security.funcs]
    getenv = ['^HUGO_', '^CI$']

  [security.http]
    methods = ['(?i)GET|POST']
    urls = ['(?i)^https?://[a-z]', '! (?i)localhost', '! @']

  [security.node]
    [security.node.permissions]
      allowaddons = ['tailwindcss']
      allowread = ['.']
      allowworker = ['tailwindcss']

```

I’m running v0.161.1.

---

<div class="post-metadata">

**Author:** ![divinerites](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/divinerites/32/12625_2.png) [@divinerites](https://discourse.gohugo.io/u/divinerites)\
**Post date:** [May 21, 2026, 3:27pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/6 "2026-05-21T15:27:58Z")

</div>

> [@jmooring](#):
>
> hugo config | grep security -A5

Sorry for the misunderstanding from my side.

```auto
% hugo config | grep security -A5
[security]
enableinlineshortcodes = true

[security.exec]
allow = [‘^(dart-)?sass(-embedded)?$’, ‘^go$’, ‘^git$’, ‘^npx$’, ‘^node$’, ‘^postcss$’, ‘^tailwindcss$’]
osenv = [‘(?i)^((HTTPS?|NO)PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\w+|(XDG_CONFIG)?HOME|USERPROFILE|SSH_AUTH_SOCK|DISPLAY|LANG|SYSTEMDRIVE|PROGRAMDATA)$’]

[security.funcs]
getenv = [‘^HUGO_’, ‘^CI$’]

[security.http]
methods = [‘(?i)GET|POST’]
urls = [‘.*’]

[security.node]
[security.node.permissions]
allowaddons = [‘tailwindcss’]
allowchildprocess = [‘tailwindcss’]
allowread = [‘.’]
allowworker = [‘tailwindcss’]

```

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [May 21, 2026, 3:33pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/7 "2026-05-21T15:33:38Z")

</div>

Are you running v0.161.0 or v0.161.1?

---

<div class="post-metadata">

**Author:** ![divinerites](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/divinerites/32/12625_2.png) [@divinerites](https://discourse.gohugo.io/u/divinerites)\
**Post date:** [May 21, 2026, 3:39pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/8 "2026-05-21T15:39:03Z")

</div>

0.161.1

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [May 21, 2026, 3:43pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/9 "2026-05-21T15:43:33Z")

</div>

I don’t have an answer for you at the moment, but the quickest solution is to disable the Node.js permission model.

```toml
[security.node.permissions]
disable = true

```

I have a site that passes the CSS resource through PostCSS with this `postcss.config.mjs` config file:

```mjs
import autoprefixer from 'autoprefixer';
import { purgeCSSPlugin } from '@fullhuman/postcss-purgecss';
const purgecss = purgeCSSPlugin({
  content: ['./hugo_stats.json'],
  defaultExtractor: content => {
    const els = JSON.parse(content).htmlElements;
    return [
      ...(els.tags || []),
      ...(els.classes || []),
      ...(els.ids || []),
    ];
  },
  // https://purgecss.com/safelisting.html
  safelist: {
    deep: [/.*tippy.*/, /^sup/]
  }
});

export default {
  plugins: [
    autoprefixer,
    process.env.HUGO_ENVIRONMENT !== 'development' ? purgecss : null
  ]
};

```

No problems, running on Ubuntu 24.04.

---

<div class="post-metadata">

**Author:** ![divinerites](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/divinerites/32/12625_2.png) [@divinerites](https://discourse.gohugo.io/u/divinerites)\
**Post date:** [May 21, 2026, 3:53pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/10 "2026-05-21T15:53:10Z")

</div>

> [@jmooring](#):
>
> I don’t have an answer for you at the moment, but the quickest solution is to disable the Node.js permission model.
> 
> ```auto
> 
> ```

Yes. Thanks. This is the cleanest quick one.  
I will try to make my head around this and post something if relevant. The doc is fine but not so easy to understand at first.

Anyway million thanks (again) for your incredible reactivity (and accuracy).

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [May 21, 2026, 3:54pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/11 "2026-05-21T15:54:36Z")

</div>

Can you post your PostCSS config file? Privately if you wish.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [May 21, 2026, 3:57pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/12 "2026-05-21T15:57:53Z")

</div>

My best guess is that this is `browserlist` (used in autoprefixer); which walks up the tree (and outside of the Hugo project) to find the first browser config. I had a similar issue in a project I tested with, and if I remember correctly they have fixed this in a recent version of browserlist so it works better with Node’s permission model. Also, there should be a way to add a browserlist config to the project itself to avoid this.

---

<div class="post-metadata">

**Author:** ![divinerites](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/divinerites/32/12625_2.png) [@divinerites](https://discourse.gohugo.io/u/divinerites)\
**Post date:** [May 21, 2026, 4:28pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/13 "2026-05-21T16:28:05Z")

</div>

I already had added a .browserslistrc  
`0.5%`  
`last 2 versions`  
`not dead`

and done  
`npx update-browserslist-db@latest`

Mmmmm. As you ask for PostCSS this site is a old one i wanted to update.  
And strangely I use “{{- $css = $css | css.PostCSS $options}}” and have no PostCSS file.

And I have import “[github.com/bep/hugo-starter-tailwind-basic/v2](http://github.com/bep/hugo-starter-tailwind-basic/v2)”, and use a “tailwind.config.js” file.

I just do not remember the rationale around this. may be the cause is in this half baked postcss/tailwind and my fault.

Will try to understand my choice digging in commits.

---

<div class="post-metadata">

**Author:** ![system](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/system/32/1_2.png) [@system](https://discourse.gohugo.io/u/system)\
**Post date:** [May 23, 2026, 4:28pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/14 "2026-05-23T16:28:36Z")

</div>

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [June 14, 2026, 4:26am UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/15 "2026-06-14T04:26:32Z")

</div>



---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [June 14, 2026, 5:04am UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/16 "2026-06-14T05:04:28Z")

</div>

I ran into this on a site hosted by Netlify:

> ERROR error building site: render: [en v1.0.0 guest] failed to render pages: render of “/opt/build/cache/hugo\_cache/modules/filecache/modules/pkg/mod/github.com/jmooring/hugo-module-feature-test@v0.6.0/content/other-tests/postcss.md” failed: “/opt/build/cache/hugo\_cache/modules/filecache/modules/pkg/mod/github.com/jmooring/hugo-module-feature-test@v0.6.0/layouts/other-tests/postcss/page.html:15:15”: execute of template failed: template: other-tests/postcss/page.html:15:15: executing “main” at \<.Content\>: error calling Content: POSTCSS: failed to transform “/temp/css” (application/octet-stream): Error: Access to this API has been restricted. Use --allow-fs-read to manage permissions.

Repository: [https://github.com/jmooring/hosting-netlify](https://github.com/jmooring/hosting-netlify)

There are no errors when I build locally, nor are there errors when using a CI/CD workflow with:

- Amplify
- Cloudflare Pages
- Cloudflare Worker
- Firebase
- GitHub Pages
- GitLab Pages
- Render
- Vercel

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [June 14, 2026, 10:51am UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/17 "2026-06-14T10:51:36Z")

</div>

> [@jmooring](#):
>
> Repository: [GitHub - jmooring/hosting-netlify: This is a test of hosting a Hugo site on Netlify · GitHub](https://github.com/jmooring/hosting-netlify)

I could get that working on Netlify by shifting to ESM style imports in the postcss config:

> <https://github.com/bep/testing101/commit/9503e42c4285d94bc5c216c78cf48df6ee26c810>

There’s a longer story here, and possibly something to be improved on in Hugo, but it’s not entirely clear to me at the moment:

- Your site also works if you run `hugo mod vendor` and commit the source, which suggests there some Node magic walking upwards.
- Your site also works if you set HUGO\_CACHEDIR to e.g. \*/opt/build/repo/.hugo\_cache"
- The error points at _/opt/build/cache/node\_modules/autoprefixer/package.json_ and Hugo’s default cache dir on Netlify is _/opt/build/cache/hugo\_cache/_ – which indicates that the overlap makes Node try to resolve inside the node\_modules cache.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [June 15, 2026, 10:55am UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/18 "2026-06-15T10:55:02Z")

</div>

> [@jmooring](#):
>
> Repository: [GitHub - jmooring/hosting-netlify: This is a test of hosting a Hugo site on Netlify · GitHub](https://github.com/jmooring/hosting-netlify)

I have tested the PR below OK on your projected in a similar setup as Netlify. I would say that Netlify (and I also think Cloudflare) way of placing a `node_modules` folder at the root of the cache dir is very shaky/buggy, but I’m guessing that ship has sailed.

> <https://github.com/gohugoio/hugo/issues/15041>
>
> Ref. @jmooring 's post here: https://discourse.gohugo.io/t/security-error-with-t…he-new-0-161-0-security-for-postcss/57186/16
> 
> This issue triggered in this case because of how Netlify stores its \`node\_modules\` cache in the same tree as the Hugo file cache. This is a hard-to-debug issue for the end user and I think we need to fix this. As I understand it, I think this is only a problem with Node's CJS resolver.
> 
> E.g. when using CJS style \`require\` in \`postcss.config.js\`
> 
> \`\`\`
> const autoprefixer = require('autoprefixer');
> module.exports = {
> plugins: \[
> autoprefixer
> \]
> }
> \`\`\`
> 
> And having a "pseudo" (very simplified) Hugo project stetup like this:
> 
> \`\`\`
> cache/node\_modules/postcss
> cache/hugo\_cache/mymodule
> hugo\_project/node\_modules/postcss
> \`\`\`
> 
> Hugo is built from \`hugo\_project\`, but Node (the CJS resolver at least) seems to walk upwards from \`mymodule\` then get \`ERR\_ACCESS\_DENIED\` for \`node\_modules/postcss\` and stops searching (see errror below). I'm not sure what the fix to this would look like, but I'm leaning against just dropping these \`ERR\_ACCESS\_DENIED\` errors and eventually fail with a error (with the \`ERR\_ACCESS\_DENIED\` info included if at all possible).
> 
> \`\`\`bash
> node:internal/modules/package\_json\_reader:125
> const parsed = modulesBinding.readPackageJSON(
> ^
> 
> Error: Access to this API has been restricted. Use --allow-fs-read to manage permissions.
> at Object.read (node:internal/modules/package\_json\_reader:125:33)
> at packageResolve (node:internal/modules/esm/resolve:770:43)
> at moduleResolve (node:internal/modules/esm/resolve:859:18)
> at defaultResolve (node:internal/modules/esm/resolve:991:11)
> at #cachedDefaultResolve (node:internal/modules/esm/loader:719:20)
> at #resolveAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:736:38)
> at nextStep (node:internal/modules/customization\_hooks:189:26)
> at resolve (data:text/javascript;base64,Ly8gTm9kZS5qcyBFU00gcmVzb2x2ZXIgaG9vayBpbnN0YWxsZWQgYnkgSHVnby4KLy8KLy8gTm9kZSdzIEVTTSByZXNvbHZlciBkb2VzIG5vdCBjb25zdWx0IE5PREVfUEFUSCwgdW5saWtlIENKUyByZXF1aXJlKCkuCi8vIFRoYXQgYnJlYWtzIHBvc3Rjc3MuY29uZmlnLmpzIC8gYmFiZWwuY29uZmlnLmpzIC8gZXRjLiBmaWxlcyB3cml0dGVuIGluCi8vIEVTTSBhbmQgbG9hZGVkIGZyb20gb3V0c2lkZSB0aGUgcHJvamVjdCB0cmVlICh0eXBpY2FsbHkgdGhlIEh1Z28gbW9kdWxlCi8vIGNhY2hlKTogYmFyZSBpbXBvcnRzIGxpa2UgYGltcG9ydCB4IGZyb20gInBvc3Rjc3MtaW1wb3J0ImAgY2Fubm90IGJlCi8vIHJlc29sdmVkIGJ5IHdhbGtpbmcgdXAgZnJvbSB0aGUgZmlsZSdzIGxvY2F0aW9uLgovLwovLyBUaGlzIGhvb2sgbWFrZXMgdGhlIEVTTSByZXNvbHZlciBmYWxsIGJhY2sgdG8gTk9ERV9QQVRIIGZvciBiYXJlCi8vIHNwZWNpZmllcnMgd2hlbiBOb2RlJ3Mgbm9ybWFsIHJlc29sdXRpb24gZmFpbHMuIEl0IGlzIGEgbm8tb3AgZm9yCi8vIHJlbGF0aXZlL2Fic29sdXRlIHBhdGhzIGFuZCBVUkwtc2NoZW1lIHNwZWNpZmllcnMsIGFuZCBpdCBuZXZlciBmaXJlcwovLyB1bmxlc3MgTm9kZSB3b3VsZCBpdHNlbGYgaGF2ZSB0aHJvd24gRVJSX01PRFVMRV9OT1RfRk9VTkQuCi8vCi8vIFVzZXMgdGhlIHN5bmNocm9ub3VzIHJlZ2lzdGVySG9va3MgQVBJIHNvIGl0IHJ1bnMgb24gdGhlIG1haW4gdGhyZWFkIGFuZAovLyBkb2VzIG5vdCByZXF1aXJlIC0tYWxsb3ctd29ya2VyIHVuZGVyIHRoZSBOb2RlIHBlcm1pc3Npb24gbW9kZWwuCgppbXBvcnQgeyByZWdpc3Rlckhvb2tzLCBjcmVhdGVSZXF1aXJlIH0gZnJvbSAnbm9kZTptb2R1bGUnOwppbXBvcnQgeyBwYXRoVG9GaWxlVVJMIH0gZnJvbSAnbm9kZTp1cmwnOwoKY29uc3QgcmVzb2x2ZXJzID0gW107CmNvbnN0IG5wID0gcHJvY2Vzcy5lbnYuTk9ERV9QQVRIOwppZiAobnApIHsKCWNvbnN0IHNlcCA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicgPyAnOycgOiAnOic7Cglmb3IgKGNvbnN0IHAgb2YgbnAuc3BsaXQoc2VwKSkgewoJCWlmIChwKSByZXNvbHZlcnMucHVzaChjcmVhdGVSZXF1aXJlKHAgKyAnL18nKSk7Cgl9Cn0KCmZ1bmN0aW9uIGlzQmFyZVNwZWNpZmllcihzKSB7CglpZiAoIXMpIHJldHVybiBmYWxzZTsKCWlmIChzLnN0YXJ0c1dpdGgoJy4nKSB8fCBzLnN0YXJ0c1dpdGgoJy8nKSB8fCBzLnN0YXJ0c1dpdGgoJyMnKSkgcmV0dXJuIGZhbHNlOwoJaWYgKC9eW2Etel1bYS16MC05Ky4tXSo6L2kudGVzdChzKSkgcmV0dXJuIGZhbHNlOwoJcmV0dXJuIHRydWU7Cn0KCnJlZ2lzdGVySG9va3MoewoJcmVzb2x2ZShzcGVjaWZpZXIsIGNvbnRleHQsIG5leHRSZXNvbHZlKSB7CgkJdHJ5IHsKCQkJcmV0dXJuIG5leHRSZXNvbHZlKHNwZWNpZmllciwgY29udGV4dCk7CgkJfSBjYXRjaCAoZXJyKSB7CgkJCWlmIChlcnI/LmNvZGUgIT09ICdFUlJfTU9EVUxFX05PVF9GT1VORCcpIHRocm93IGVycjsKCQkJaWYgKCFpc0JhcmVTcGVjaWZpZXIoc3BlY2lmaWVyKSkgdGhyb3cgZXJyOwoJCQlmb3IgKGNvbnN0IHIgb2YgcmVzb2x2ZXJzKSB7CgkJCQl0cnkgewoJCQkJCWNvbnN0IHJlc29sdmVkID0gci5yZXNvbHZlKHNwZWNpZmllcik7CgkJCQkJcmV0dXJuIHsgdXJsOiBwYXRoVG9GaWxlVVJMKHJlc29sdmVkKS5ocmVmLCBzaG9ydENpcmN1aXQ6IHRydWUsIGZvcm1hdDogbnVsbCB9OwoJCQkJfSBjYXRjaCAoXykgeyAvKiB0cnkgbmV4dCAqLyB9CgkJCX0KCQkJdGhyb3cgZXJyOwoJCX0KCX0sCn0pOwo=:39:11)
> at nextStep (node:internal/modules/customization\_hooks:189:26)
> at resolveWithHooks (node:internal/modules/customization\_hooks:417:10) {
> code: 'ERR\_ACCESS\_DENIED',
> permission: 'FileSystemRead',
> resource: '/Users/bep/dev/dump/testinroot/node\_modules/postcss/package.json'
> }
> 
> Node.js v24.14.1
> \`\`\`

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [June 18, 2026, 7:53pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/19 "2026-06-18T19:53:02Z")

</div>

In our documentation, the configuration files used with `css.PostCSS`, `js.Babel`, and `resources.PostProcess` are now shown as `.mjs` files using ESM syntax.

This works fine on Netlify as noted above, and with v0.163.3 and later the `.mjs` files can also be used in modules.

---

<div class="post-metadata">

**Author:** ![baltpeter](https://avatars.discourse-cdn.com/v4/letter/b/ecb155/32.png) [@baltpeter](https://discourse.gohugo.io/u/baltpeter)\
**Post date:** [June 29, 2026, 9:52pm UTC](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186/20 "2026-06-29T21:52:30Z")

</div>

If you use the `postcss-preset-env` plugin, there is an additional error, even after converting the config to ESM:

```auto
ERROR error building site: render: [de v1.0.0 guest] failed to render pages: render of "/my/path/content/de/blog/myblog/index.md" failed: "/my/path/layouts/_default/baseof.html:35:42": execute of template failed: template: single.html:35:42: executing "single.html" at <$style.RelPermalink>: error calling RelPermalink: POSTCSS: failed to transform "/styles/index.css" (text/css): 
Error: Access to this API has been restricted. Use --allow-fs-read to manage permissions.
    at Object.existsSync (node:fs:289:18)
    at isFile (/my/path/node_modules/browserslist/node.js:42:19)
    at /my/path/node_modules/browserslist/node.js:200:16
    at eachParent (/my/path/node_modules/browserslist/node.js:53:18)
    at Object.getStat (/my/path/node_modules/browserslist/node.js:198:15)
    at Object.browserslist [as default] (/my/path/node_modules/browserslist/index.js:439:19)
    at plugin (/my/path/node_modules/postcss-preset-env/dist/index.js:437:61)
    at file:///my/path/postcss.config.mjs?t=1782769228990:12:9
    at ModuleJob.run (node:internal/modules/esm/module_job:413:25)
    at async onImport.tracePromise. __proto__ (node:internal/modules/esm/loader:660:26) {
  code: 'ERR_ACCESS_DENIED',
  permission: 'FileSystemRead',
  resource: '/my/browserslist-stats.json'
}

```

The problem is that Browserslist walks up the directory tree until it finds a `browserlists-stats.json`: [browserslist/node.js at 03ba4e2724b4f77c408498d937c352c2e38f9e72 · browserslist/browserslist · GitHub](https://github.com/browserslist/browserslist/blob/03ba4e2724b4f77c408498d937c352c2e38f9e72/node.js#L297-L305)

If there isn’t one in the project directory, Hugo blocks the reads by default.

I was able to solve this by explicitly allowing the reads in my config:

```toml
[security]
  [security.node]
    [security.node.permissions]
      allowRead = ['.', '/**/browserslist-stats.json']

```

Alternatively, you could also just create a `browserslist-stats.json` containing an empty object (`{}`).

[Next page](https://discourse.gohugo.io/t/security-error-with-the-new-0-161-0-security-for-postcss/57186.md?page=2)
