crowdsecurity/crowdsec · error
decompress initial bundle: %w
Error message
decompress initial bundle: %w
What it means
After opening the embedded initial_bundle.js.gz, the runtime reads the decompressed content with io.ReadAll; a failure here means the gzip stream is truncated or corrupted mid-decompression. The error is stored in initialBundleErr and returned for every request to the bundle endpoint. It signals a broken embedded asset in the binary.
Source
Thrown at pkg/appsec/challenge/static_bundle.go:65
func (c *ChallengeRuntime) seedCacheFromInitialBundle() error {
initialBundleOnce.Do(func() {
decompressStart := time.Now()
if len(initialBundleGz) == 0 {
initialBundleErr = errors.New("baked-in initial_bundle.js.gz is empty (was `go generate` run?)")
return
}
gz, err := gzip.NewReader(bytes.NewReader(initialBundleGz))
if err != nil {
initialBundleErr = fmt.Errorf("gzip reader for initial bundle: %w", err)
return
}
defer gz.Close()
decoded, err := io.ReadAll(gz)
if err != nil {
initialBundleErr = fmt.Errorf("decompress initial bundle: %w", err)
return
}
initialBundle = string(decoded)
c.log().WithFields(log.Fields{
"compressed_bytes": len(initialBundleGz),
"decompressed_bytes": len(initialBundle),
"duration_ms": time.Since(decompressStart).Milliseconds(),
}).Debug("decompressed baked-in obfuscated challenge code")
})
if initialBundleErr != nil {
return initialBundleErr
}
if initialBundle == "" {
return errors.New("initial bundle is empty after decompression")
}
View on GitHub (pinned to 909b515798)
Solutions
- Regenerate the asset: delete initial_bundle.js.gz, re-run `go generate`, and rebuild
- Validate the asset: `gzip -t initial_bundle.js.gz` must report OK
- Compare the .gz checksum/size against a known-good build to spot truncation
- Rebuild in a clean environment (fresh clone, adequate disk space) to rule out cache/transfer corruption
Example fix
# before: corrupted embedded asset $ curl localhost:8080/.well-known/appsec/initial_bundle.js # error: decompress initial bundle: unexpected EOF # after go generate ./pkg/appsec/challenge/... && make build
Defensive patterns
Strategy: try-catch
Validate before calling
if !bytes.HasPrefix(initialBundleGz, []byte{0x1f, 0x8b}) {
return errors.New("embedded bundle is not gzip")
}
if zr, err := gzip.NewReader(bytes.NewReader(initialBundleGz)); err == nil {
if _, err := io.ReadAll(zr); err != nil { return fmt.Errorf("truncated bundle: %w", err) }
} Try / catch
bundle, err := challenge.InitialBundle()
if err != nil {
log.Error().Err(err).Msg("embedded bundle decompression failed; rebuild required")
http.Error(w, "bundle unavailable", http.StatusInternalServerError)
return
} Prevention
- Run `gzip -t` on the generated asset in CI
- Rebuild after any interrupted go:generate
- Watch for LFS/git filters touching .gz files; verify checksums
- Ensure adequate disk space during asset generation
When it happens
Trigger: initialBundleGz passes gzip.NewReader's header check but its deflate stream is truncated or bit-flipped — e.g. a partial file was embedded because go:generate was interrupted or the asset was corrupted in the repo/build.
Common situations: Interrupted go:generate leaving a half-written .gz; LFS or git-smudge/clean filters corrupting binary assets; flaky CI artifact transfers; disk-full during the generate step.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- gzip reader for initial bundle: %w
- failed to create gzip reader for obfuscator wasm: %w
- failed to decompress obfuscator wasm: %w
- esbuild returned no output files
- obfuscator produced empty output
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/5105c8ec3a5a8039.
Report an issue: GitHub.