nektos/act · critical
generate auth token: %w
Error message
generate auth token: %w
What it means
The artifact cache server generates a random 16-byte auth token (crypto/rand) that scopes every HTTP route ('/<token>/api/...'). If rand.Read fails — which for crypto/rand realistically means the OS entropy source is unavailable or blocked — server startup aborts with the wrapped 'generate auth token: %w' error before the HTTP router is created.
Source
Thrown at pkg/artifactcache/handler.go:92
return nil, err
}
h.storage = storage
if customExternalURL != "" {
h.customExternalURL = customExternalURL
}
if outboundIP != "" {
h.outboundIP = outboundIP
} else if ip := common.GetOutboundIP(); ip == nil {
return nil, fmt.Errorf("unable to determine outbound IP address")
} else {
h.outboundIP = ip.String()
}
tokenBytes := make([]byte, 16)
if _, err := rand.Read(tokenBytes); err != nil {
return nil, fmt.Errorf("generate auth token: %w", err)
}
h.token = hex.EncodeToString(tokenBytes)
router := httprouter.New()
base := "/" + h.token + apiPath
router.GET(base+"/cache", h.middleware(h.find))
router.POST(base+"/caches", h.middleware(h.reserve))
router.PATCH(base+"/caches/:id", h.middleware(h.upload))
router.POST(base+"/caches/:id", h.middleware(h.commit))
router.GET(base+"/artifacts/:id", h.middleware(h.get))
router.POST(base+"/clean", h.middleware(h.clean))
h.router = router
h.gcCache()
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", h.outboundIP, port))
if err != nil {View on GitHub (pinned to 4f41128141)
Solutions
- Verify the OS entropy source: check that /dev/urandom is readable and getrandom is not blocked by seccomp/apparmor profiles.
- If running act in a container, allow getrandom(2) in the security profile or use a less restrictive runtime.
- On entropy-starved VMs, wait until the pool is ready or install haveged/virtio-rng.
- Update the Go toolchain / act build if the failure persists, since older runtimes had entropy bugs on some platforms.
Example fix
# before act -j build # inside container with seccomp blocking getrandom # -> generate auth token: ... # after # run with a profile permitting getrandom, e.g.: docker run --security-opt seccomp=unconfined ... act -j build
Defensive patterns
Strategy: retry
Validate before calling
package main
import (
"crypto/rand"
"fmt"
"os"
)
func entropyAvailable() error {
f, err := os.Open("/dev/urandom")
if err != nil {
return fmt.Errorf("entropy source unavailable: %w", err)
}
defer f.Close()
buf := make([]byte, 8)
if _, err := rand.Read(buf); err != nil {
return fmt.Errorf("crypto/rand read failed: %w", err)
}
return nil
} Try / catch
handler, err := artifactcache.NewHandler(...)
if err != nil && strings.Contains(err.Error(), "generate auth token") {
// entropy starvation can be transient on cold VMs: brief retry before failing
time.Sleep(2 * time.Second)
handler, err = artifactcache.NewHandler(...)
if err != nil {
return fmt.Errorf("system entropy unavailable (getrandom blocked?); fix sandbox/kernel: %w", err)
}
} Prevention
- Permit getrandom(2) in container seccomp profiles running act.
- Install virtio-rng/haveged on entropy-starved VMs.
- Treat repeated crypto/rand failures as an environment defect, not a code bug.
When it happens
Trigger: Starting act (or NewHandler directly) on a system where crypto/rand cannot read entropy: early-boot entropy starvation on minimal VMs/containers, a broken /dev/urandom, or seccomp/container runtimes blocking getrandom(2).
Common situations: act inside tightly sandboxed containers with syscalls filtered; embedded/minimal systems before the entropy pool is initialized; rare kernel/runtime misconfigurations; Go runtimes on platforms with faulty entropy plumbing.
Related errors
- unable to determine outbound IP address
- cache %d: not reserved
- cache %v %q: already complete
- find cache: %w
- insert cache: %w
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/6796b3fe5058e765.
Report an issue: GitHub.