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

  1. Restore access to the OS entropy source: allow the getrandom syscall in the container/seccomp profile or mount /dev/urandom
  2. Upgrade the container runtime/seccomp profile (e.g. docker>=20.10 default profiles allow getrandom)
  3. Rerun the process on a host with a working CSPRNG — verify with `head -c 16 /dev/urandom | xxd`
  4. 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

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


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/d4275b785da90a3f. Report an issue: GitHub.