Cloudflare Pages + Hugo: Node.js Permission Error (ERR_ACCESS_DENIED) – Riešenie

Kompletné riešenie Node.js ERR_ACCESS_DENIED na Cloudflare Pages. Krok za krokom s citáciami a osvedčenými postupmi.

Problém: Cloudflare Pages zlyha s ERR_ACCESS_DENIED

Build úspešne prejde lokálne, ale na Cloudflare Pages zlyha:

panic: POSTCSS: failed to transform "css/hb.css" (text/css):
Error: Access to this API has been restricted. Use --allow-fs-read to manage permissions.
  code: 'ERR_ACCESS_DENIED',
  permission: 'FileSystemRead',
  resource: '/opt/buildhome/.cache/hugo_cache/modules/filecache/.../package.json'

Príčina

Od Hugo v0.160 (apríl 2026) bol zavedený Node.js permission model, ktorý spúšťa Node tools (PostCSS, TailwindCSS, Babel) s --permission flagom. Cloudflare Pages má globálne cache mimo projektu, takže PostCSS nemôže čítať konfigurácie mimo . (projekt).

Zdroj: Hugo v0.160 Release Notes – “Harden Node tool execution with –permission flag”


Overené riešenie pre Cloudflare Pages

Krok 1: Vytvorte postcss.config.mjs (ESM formát)

Premenujte postcss.config.jspostcss.config.mjs a použite ESM syntax:

 1// postcss.config.mjs
 2import autoprefixer from 'autoprefixer'
 3
 4const isDev = process.env.HUGO_ENVIRONMENT === 'development'
 5
 6export default {
 7  plugins: [
 8    !isDev ? autoprefixer : null
 9  ],
10  map: isDev ? { inline: true } : false
11}

Prečo ESM?

  • Hugo v0.163.3+ má lepšiu ESM resolver integrácií
  • ESM obchádza CJS resolver problémy
  • Funguje na Cloudflare Pages, Netlify aj lokálne

Krok 2: Nastavte Hugo security config

V config/_default/hugo.yaml pridajte:

 1security:
 2  node:
 3    permissions:
 4      allowRead:
 5        - '.'                          # Projekt
 6        - '/**/browserslist*'          # Browserslist config
 7        - '/**/package.json'           # package.json kdekoľvek
 8        - '/**/node_modules/**'        # Node modules
 9      allowAddons:
10        - tailwindcss
11      allowWorker:
12        - tailwindcss
13      allowChildProcess:
14        - tailwindcss

Krok 3: Commitujte dependency lockfiles

1git add package-lock.json go.sum
2git commit -m "Lock dependencies for CI/CD builds"
3git push

Prečo?

  • Cloudflare sa nemusí sťahovať moduly znova
  • Determinované buildy
  • Rýchlejší deployment

Krok 4: Overenie na Cloudflare Pages

V Cloudflare Pages dashboard:

  1. Settings > Build > Build command: npm ci && hugo --minify --gc
  2. Settings > Build > Build directory: public
  3. Settings > Environment variables (voliteľne):
    • HUGO_VERSION: 0.164.0 (alebo novšia)
    • NODE_VERSION: 22.16.0 (alebo novšia)

Ak máte HB Stack modul, skontrolujte, že package-lock.json je commitnutý.


Overený postup: blog.roran60.com (HB Stack)

Podľa Hugo Discourse diskusie a GitHub Issue #15041, tu je overená postupnosť krokov.

Krok 1: Lokálne testovanie

1# Vymaž cache
2rm -rf resources/ .hugo_cache/
3
4# Build ako na Cloudflare
5npm ci
6hugo --minify --gc

Ak build projde bez chyby, problém je iba na Cloudflare Pages.

Krok 2: Aplikuj jedno z riešení

Variant A (odporúčané): Vypni sandbox v config

1# Uprav config/_default/hugo.yaml
2# Pridaj:
3# security:
4#   node:
5#     permissions:
6#       disable: true

Variant B: Alebo skúsime ESM config (bezpečnejšie)

1# Premenuj postcss.config.js na postcss.config.mjs
2# a použij ESM syntax (viď vyššie)

Krok 3: Commitni a push

1git add config/_default/hugo.yaml package-lock.json go.sum
2git commit -m "Fix Node.js permission error on Cloudflare Pages"
3git push

Krok 4: Overenie na Cloudflare Pages

V Cloudflare Pages dashboard:

  • Settings > Build > Build command: npm ci && hugo --minify --gc
  • Settings > Build > Build directory: public
  • Nový build by mal prejsť bez chyby

Podľa Cloudflare Pages dokumentácie, environment by mal automaticky nainštalovať Hugo a NPM dependencies.


Rýchle riešenie: Vypnúť Node.js sandbox (permissions model)

Ak vám všetky vyššie riešenia nefungujú alebo chcete najrýchlejší workaround, môžete vypnúť Node.js permission model. Toto je odporúčané riešenie od Hugo maintainerov pre prípad, keď permissions spôsobujú problémy.

Možnosť A: Vypnúť v Hugo config (ODPORÚČANÉ)

V config/_default/hugo.yaml pridajte:

1security:
2  node:
3    permissions:
4      disable: true

Prečo to funguje?

  • Hugo prestane spúšťať Node tools s --permission flagom
  • PostCSS bude mať prístup ku všetkým súborom
  • Chyba zmizne ihneď

Bezpečnosť:

  • Hugo je trusted tool (spúšťate ho vy)
  • Podľa Hugo Issue #15041: “najrýchlejšie riešenie je vypnúť Node.js permission model”
  • Vhodné pre private blogs a vlastné projekty

Commit a push:

1git add config/_default/hugo.yaml
2git commit -m "Disable Node.js permissions (ERR_ACCESS_DENIED workaround)"
3git push

Možnosť B: Vypnúť pomocou NODE_OPTIONS (bez zmeny súborov)

V Cloudflare Pages dashboard > Settings > Build > Environment variables:

Meno Hodnota
NODE_OPTIONS --no-experimental-permission

Potom normálny build command:

npm ci && hugo --minify --gc

Výhody:

  • Bez zmeny v repozitári
  • Skúšanie bez commitnutia
  • Dočasne, len na Cloudflare Pages

Možnosť C: Vypnúť len PostCSS (najjemnejšie riešenie)

Podľa Hugo dokumentácie, môžete vyňať PostCSS z security allow listu:

V config/_default/hugo.yaml:

1security:
2  exec:
3    allow:
4      - '^(dart-)?sass(-embedded)?$'
5      - '^go$'
6      - '^git$'
7      - '^node$'
8      # - '^postcss$'  <- ZAKOMENTOVANÉ (vypnutá security)
9      - '^tailwindcss$'

Výhody:

  • Sandbox stále zapnutý pre ostatné tools
  • Len PostCSS bez permissions
  • Balančuje bezpečnosť + kompatibilitu

Alternatívne riešenia (ak vyššie nefungovalo)

Riešenie: Rozšíriť allowRead na všetko

1security:
2  node:
3    permissions:
4      allowRead:
5        - '.'
6        - '*'  # Všetky súbory (menej bezpečné, ale jemnejšie ako disable)

Commit:

1git add config/_default/hugo.yaml
2git commit -m "Expand Node.js permissions for Cloudflare Pages"
3git push

Riešenie: Nastaviť HUGO_CACHEDIR

V Cloudflare Pages environment variables:

HUGO_CACHEDIR=./.hugo_cache

Niekedy pomôže, ak je cache umiestnený v projekte.


Diagnostika

1. Lokálny build s logom

1hugo --logLevel=debug 2>&1 | grep -i "postcss\|permission\|access"

2. Konfigúracia si overenie

1hugo config | grep -A 20 security

3. Cloudflare Pages logy

V Cloudflare dashboard > Deployments > Zvolte failed build > View build log:

Hľadajte:

ERR_ACCESS_DENIED
FileSystemRead
resource: /path/to/file

FAQ

Q: Môžem mať postcss.config.js aj postcss.config.mjs?

A: Nie, Hugo hľadá v tomto poradí: .mjs.js.cjs. Mať obidva je matúce. Staň sa pri .mjs.


Q: Musím commitnúť resources/ priečinok?

A: Nie je povinné, ale je silne odporúčané na CI/CD. Image processing cache urýchľuje build o minúty.

1git add resources/
2git commit -m "Cache image resources for faster builds"

Q: Prečo to funguje lokálne ale nie na Cloudflare?

A: Lokálny Hugo má prístup k všetkým súborom. Cloudflare Pages permissions ide prísnejšie. ESM config + allowRead pravidlá to riešia.


Q: Čo ak mám TailwindCSS alebo Babel?

A: Rovnaké pravidlá. Všetky Node tools (PostCSS, TailwindCSS, Babel) sa spúšťajú s rovnakými permissions. Konfigurácia vyššie ich pokrýva.

1security:
2  node:
3    permissions:
4      allowAddons:
5        - tailwindcss
6      allowWorker:
7        - tailwindcss

Q: Je to bezpečné vypnúť Node permissions úplne?

A: Áno, pre private projekty je to bezpečné. Hugo je trusted tool a spúšťate ho vy, nie hostingová platforma. Ide len o to, že Node.js sandbox (introduced v Hugo 0.160) zamedzuje file system prístupom mimo projektu. Ak sa vám páči prísnosť, ponechajte si ESM config + allowRead. Ak chcete rýchle riešenie bez problémov, vypnite sandbox.


Q: Aký je rozdiel medzi disable: true a NODE_OPTIONS?

A: Obe fungujú rovnako:

  • disable: true v Hugo config = permanent (uložené v repozitári)
  • NODE_OPTIONS v Cloudflare env = dočasné (iba na CI/CD)

Ak plánujete mať to trvale, použite disable: true. Ak skúšate workaround, skúste NODE_OPTIONS bez zmeny súborov.


Q: Je to bezpečné expandovať permissions s allowRead: ['*']?

A: Áno, je to bezpečnejšie než disable: true. Stále máte file system kontrolu, len čítanie všetkých súborov. Dopĺňa sa to medzi:

  • ESM config + allowRead: [’//node_modules/’] – bezpečnejšie, robustnejšie
  • ⚠️ allowRead: [’*’] – menej bezpečné, ale stále kontrolované
  • disable: true – úplne bez sandbox

Prehľad verzií a ich správa

Hugo verzia PostCSS support Node permissions ESM support Odporúčanie
< 0.160 ✅ Funguje ❌ Nie ❌ Nie Upgrade
0.160–0.162 ⚠️ Problémy ✅ Ano ⚠️ Slabé Upgrade
0.163.0+ ✅ OK ✅ Ano ✅ Ano Používajte
0.164+ ✅ Optimálny ✅ Ano ✅ Ano Ideálny

Checklist pred deployom

Variant 1: ESM config (odporúčané) ✅

  • Lokálne npm ci && hugo --minify --gc prejde bez chyby
  • Máte postcss.config.mjs (ESM, nie CJS)
  • config/_default/hugo.yaml má security settings s allowRead
  • Commitnutý package-lock.json a go.sum
  • Cloudflare Pages build command je npm ci && hugo --minify --gc
  • Cloudflare build directory je public
  • Hugo verzia na Cloudflare je aspoň 0.163.0

Variant 2: Vypnutý sandbox (workaround) ⚡

  • V config/_default/hugo.yaml je security.node.permissions.disable: true
  • Commitnutý package-lock.json a go.sum
  • Cloudflare Pages build command je npm ci && hugo --minify --gc
  • Cloudflare build directory je public

Zdroje a referencie

Zdroj URL Poznámka
Hugo v0.160 Release gohugo.io releases Zavedenie Node.js permission modelu
Hugo Issue #15041 github.com/gohugoio/hugo/issues/15041 CJS resolver problém – diskusia s maintainermi
Hugo Discourse discourse.gohugo.io/t/57186 PostCSS ERR_ACCESS_DENIED problém a riešenia
Hugo Security Docs gohugo.io/functions/css/postcss PostCSS konfigurácia a Node permissions
Cloudflare Pages Hugo gohugo.io/host-and-deploy/host-on-cloudflare Deploy na Cloudflare s Hugo
Node.js Permissions nodejs.org/api/permissions.html Node.js permission model dokumentácia
Cloudflare Pages Docs developers.cloudflare.com/pages Build environment a verzie nástrojov

Záver

Rýchle riešenie: security.node.permissions.disable: true v config/_default/hugo.yaml

Bezpečnejšie riešenie: ESM config (postcss.config.mjs) + allowRead pravidlá

Cloudflare Pages + Hugo 0.163+ + ESM PostCSS = stabilný, bezpečný build.

Postupujte podľa checklistu vyššie a problémy by mali zmiznúť. Ak nie, skontrolujte Cloudflare build logy.