ory/hydra · critical
cannot generate nonce
Error message
cannot generate nonce
What it means
After creating the AEAD, PageToken.encrypt generates a random nonce with crypto/rand.Read to prepend to the ciphertext. rand.Read on crypto/rand essentially never fails except when the OS entropy source is unavailable/broken, so this error signals a system-level RNG failure.
Source
Thrown at oryx/pagination/keysetpagination_v2/page_token.go:192
func NewPageToken(cols ...Column) PageToken { return PageToken{cols: cols} }
func (t *PageToken) encrypt(key [32]byte) (string, error) {
raw, err := json.Marshal(t)
if err != nil {
return "", errors.Wrap(err, "cannot marshal page token")
}
a, err := aead.New(key)
if err != nil {
return "", errors.Wrap(err, "cannot create AEAD")
}
// The nonce is prepended to the ciphertext. AEADs that manage the nonce
// internally report a nonce size of zero, so this also covers them.
nonce := make([]byte, a.NonceSize())
if _, err := rand.Read(nonce); err != nil {
return "", errors.Wrap(err, "cannot generate nonce")
}
return base64.URLEncoding.EncodeToString(a.Seal(nonce, nonce, raw, []byte(pageTokenContext))), nil
}
func (t *PageToken) decrypt(key [32]byte, s string) error {
if s == "" {
return errors.WithStack(ErrInvalidPaginationToken())
}
raw, err := base64.URLEncoding.DecodeString(s)
if err != nil {
return errors.WithStack(ErrInvalidPaginationToken())
}
dec, err := openAEAD(key, raw)
if err != nil {
// Tokens issued before the switch to a context-bound AEAD are sealedView on GitHub (pinned to 4174065ffb)
Solutions
- Verify /dev/urandom exists and is readable inside the container: ls -l /dev/urandom
- Check seccomp/apparmor policies are not blocking getrandom(2) syscall
- Update the base image/kernel so getrandom is available
- Retry the deployment on a known-good host to confirm it is environment-specific
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: ensure the entropy source is readable at startup
if _, err := os.Stat("/dev/urandom"); err != nil {
log.Fatal("crypto entropy source unavailable: /dev/urandom missing")
}
if _, err := rand.Read(make([]byte, 16)); err != nil {
log.Fatal("crypto/rand unavailable at startup")
} Try / catch
enc, err := Encrypt(key, token)
if err != nil && strings.Contains(err.Error(), "cannot generate nonce") {
// environment-level RNG failure: retry once, then surface as 500
return nil, status.Error(codes.Internal, "system RNG unavailable")
} Prevention
- Verify /dev/urandom is present in container images (no distroless stripping of it)
- Audit seccomp/apparmor profiles for getrandom(2) blocks
- Do a crypto/rand smoke check during application startup
- Run crypto/rand reads on the main runtime, not inside chrooted/sandboxed helpers
When it happens
Trigger: crypto/rand.Read returns an error during Encrypt — typically on systems where /dev/urandom is inaccessible, in heavily restricted containers/chroots, or with a broken Go runtime entropy setup.
Common situations: Running in a container with no access to the kernel RNG device, seccomp policies blocking getrandom(2), or exotic sandboxes (some CI environments, old kernels without getrandom and blocked /dev/urandom).
Related errors
- jwks: unable to generate key
- cookiex: at least one secret is required
- ErrUnknownHashAlgorithm
- ErrInvalidHash
- ErrMismatchedHashAndPassword
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/98ca27a5ac2ed202.
Report an issue: GitHub.