quasarframework/quasar · error · TypeError
Invalid SSR nonce. Expected a non-empty base64 or base64url
Error message
Invalid SSR nonce. Expected a non-empty base64 or base64url value.
What it means
injectNonceAttr copies a CSP nonce into the SSR render context so rendered tags get a nonce attribute. It throws a TypeError when the provided nonce is not a non-empty string matching the base64/base64url pattern (nonceRE), because a malformed nonce would produce an invalid Content-Security-Policy header or enable markup injection.
Source
Thrown at app-vite/templates/entry/ssr-nonce.js:19
const nonceRE = /^[A-Za-z0-9+/_-]+={0,2}$/
const htmlCharsRE = /[&<>"']/g
const encodeHtmlChars = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
}
export function injectNonceAttr(ssrContext) {
const { nonce } = ssrContext
if (!nonce) {
ssrContext.__quasarNonceAttr = ''
return
}
if (typeof nonce !== 'string' || !nonceRE.test(nonce)) {
throw new TypeError(
'Invalid SSR nonce. Expected a non-empty base64 or base64url value.'
)
}
const value = nonce.replaceAll(htmlCharsRE, char => encodeHtmlChars[char])
ssrContext.__quasarNonceAttr = ` nonce="${value}"`
}
View on GitHub (pinned to 4841521b5f)
Solutions
- Generate the nonce with crypto.randomBytes(16).toString('base64') (or 'base64url')
- Verify the value reaches the app non-empty (log it in dev) — empty nonces are allowed (no attribute) but whitespace/junk is not
- Strip quotes/whitespace and any surrounding markup from upstream-provided nonces
- Do not pre-HTML-escape the nonce; the helper escapes HTML characters itself
Example fix
// before
const nonce = crypto.randomBytes(16).toString('hex') // invalid: hex not base64
// after
const nonce = crypto.randomBytes(16).toString('base64') Defensive patterns
Strategy: type-guard
Validate before calling
const nonceRE = /^[A-Za-z0-9+/_-]+={0,2}$/
function isValidNonce(nonce) {
return typeof nonce === 'string' && nonceRE.test(nonce)
}
if (nonce != null && !isValidNonce(nonce)) throw new TypeError('nonce must be base64/base64url') Type guard
function isValidNonce(v) {
return typeof v === 'string' && /^[A-Za-z0-9+/_-]+={0,2}$/.test(v)
} Try / catch
try {
await ssrRender({ nonce })
} catch (err) {
if (err instanceof TypeError && err.message.includes('Invalid SSR nonce')) {
// regenerate the nonce: crypto.randomBytes(16).toString('base64')
} else throw err
} Prevention
- Always generate nonces via crypto.randomBytes(n).toString('base64') or 'base64url'
- Never pass hex-encoded or pre-HTML-escaped values as nonces
- Empty string is permitted (means no nonce attribute); sanitize upstream headers before use
- Add a startup assertion validating the nonce in dev mode
When it happens
Trigger: Setting an SSR nonce via configuration/env (the value consumed by renderSsrContext, #runVite or renderSsgPage) that is empty, undefined-as-string with wrong chars, contains '<', '"' or other non-base64 characters, or is not a string at all.
Common situations: Generating a nonce with crypto.randomBytes without .toString('base64'/'base64url'); passing a hex-encoded nonce; middleware reading an empty CSP nonce header from upstream; accidentally HTML-escaping the nonce before handing it over.
Related errors
- Please remove ${attachMarkup} from /index.html inside of <bo
- Build output directory must be a non-empty path
- Project directory must be a non-empty path
- quasar.config file > invalid Vite plugin specified: ${name}
- The BEX manifest requires a "manifest_version" prop, which i
AI-assisted analysis of quasarframework/quasar@4841521b5f (2026-08-30).
Data as JSON: /api/errors/3139a65043d652da.
Report an issue: GitHub.