anomalyco/sst · critical
panic(err)
Error message
panic(err)
What it means
pkg/id generates 24-character time-sortable IDs, combining the current timestamp with bytes read from crypto/rand. crypto/rand.Read fails only when the operating system's cryptographic entropy source is unavailable; the library treats this as unrecoverable (IDs must be unpredictable) and panics. Ascending() and Descending() both funnel through generateID, so any caller panics.
Source
Thrown at pkg/id/id.go:33
func Descending() string {
return generateID(true)
}
func generateID(descending bool) string {
now := time.Now().UnixMilli()
if descending {
now = ^now
}
timeBytes := make([]byte, 6)
for i := 0; i < 6; i++ {
timeBytes[i] = byte(now >> (40 - 8*i))
}
randomBytes := make([]byte, (LENGTH-12)/2)
_, err := rand.Read(randomBytes)
if err != nil {
panic(err)
}
result := make([]byte, LENGTH)
hex.Encode(result[:12], timeBytes)
hex.Encode(result[12:], randomBytes)
return string(result)
}
View on GitHub (pinned to a0bd20f762)
Solutions
- Restore access to the OS entropy source: allow the getrandom syscall in the container/seccomp profile or mount /dev/urandom
- Upgrade the container runtime/seccomp profile (e.g. docker>=20.10 default profiles allow getrandom)
- Rerun the process on a host with a working CSPRNG — verify with `head -c 16 /dev/urandom | xxd`
- If you control the code, replace panic with error propagation, though SST treats RNG failure as fatal by design
Example fix
// before (seccomp profile json)
"syscalls": [{ "names": ["getrandom"], "action": "SCMP_ACT_ERRNO" }]
// after
remove the getrandom deny rule, or run with: docker run --security-opt seccomp=default.json ... Defensive patterns
Strategy: try-catch
Validate before calling
// verify the CSPRNG is reachable before invoking sst code paths that generate IDs
f, err := os.Open("/dev/urandom")
if err != nil {
return fmt.Errorf("entropy source unavailable: %w", err)
}
f.Close() Try / catch
// cannot recover from the panic itself (library-level); guard the calling operation and surface a clear message:
func safeAscending() (id string, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("id generation failed (check CSPRNG/seccomp getrandom): %v", r)
}
}()
return id.Ascending(), nil
} Prevention
- Allow the getrandom syscall in container seccomp/AppArmor profiles
- Keep /dev/urandom mounted in minimal containers
- Test ID-generation-dependent code paths in the same sandbox used in production
- Pin a modern container runtime whose default seccomp profile permits getrandom
When it happens
Trigger: Any call to id.Ascending() or id.Descending() when crypto/rand.Read errors — practically only when the OS CSPRNG is unavailable: a sealed /dev/urandom-less container, getrandom(2) returning ENOSYS/EAGAIN repeatedly, or an extremely restricted seccomp/AppArmor profile blocking getrandom.
Common situations: Minimal Docker containers with restricted syscalls (seccomp profiles blocking getrandom on old Docker + new kernels); embedded/unusual Linux setups without a functional entropy pool; sandboxed CI environments.
Related errors
- panic(err)
- panic(err)
- not found
- expect JSON object open with '{'
- expecting JSON key should be always a string: %T: %v
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/d4275b785da90a3f.
Report an issue: GitHub.