{"record":{"id":"787fdc5fb2bd92b1","repo":"crowdsecurity/crowdsec","slug":"failed-to-create-gzip-reader-for-obfuscator-wasm","errorCode":null,"errorMessage":"failed to create gzip reader for obfuscator wasm: %w","messagePattern":"failed to create gzip reader for obfuscator wasm: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/appsec/challenge/challenge.go","lineNumber":317,"sourceCode":"\treturn nil\n}\n\n// NewChallengeRuntime builds and starts a ChallengeRuntime: it initializes the\n// wazero runtime, decompresses the baked-in library bundle, derives the master\n// secret + keyring, pre-warms the dynamic-module cache, and (if configured)\n// spawns the background obfuscation refresher. Safe for concurrent use across\n// all appsec runners. Pass WithXxx options to override defaults.\n// compileObfuscatorModule decompresses the baked-in obfuscator WASM (once,\n// process-wide) and compiles it for the given runtime. Pre-compiling lets each\n// ObfuscateJS call merely instantiate the module instead of re-parsing the WASM\n// bytes, which would otherwise cost ~4-5s per call.\nfunc compileObfuscatorModule(ctx context.Context, r wazero.Runtime) (wazero.CompiledModule, error) {\n\tvar obfuscatorWasmErr error\n\n\tobfuscatorWasmOnce.Do(func() {\n\t\tzr, err := gzip.NewReader(bytes.NewReader(obfuscatorWasmGz))\n\t\tif err != nil {\n\t\t\tobfuscatorWasmErr = fmt.Errorf(\"failed to create gzip reader for obfuscator wasm: %w\", err)\n\t\t\treturn\n\t\t}\n\t\tdefer zr.Close()\n\n\t\tobfuscatorWasm, err = io.ReadAll(zr)\n\t\tif err != nil {\n\t\t\tobfuscatorWasmErr = fmt.Errorf(\"failed to decompress obfuscator wasm: %w\", err)\n\t\t\treturn\n\t\t}\n\t})\n\n\tif obfuscatorWasmErr != nil {\n\t\treturn nil, obfuscatorWasmErr\n\t}\n\n\tcompiledMod, err := r.CompileModule(ctx, obfuscatorWasm)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to compile obfuscator wasm module: %w\", err)","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/challenge.go#L299-L335","documentation":"This error is returned by compileObfuscatorModule when gzip.NewReader fails on the embedded, gzip-compressed obfuscator WASM binary. Since obfuscatorWasmGz is a compile-time embedded byte slice, this almost certainly means the embedded asset is corrupt, truncated, or was produced by a bad build step. The error is wrapped with %w so the underlying gzip error (e.g. gzip: invalid header) is preserved.","triggerScenarios":"Calling NewChallengeRuntime (directly or via Configure) when the embedded obfuscatorWasmGz byte slice cannot be opened as a valid gzip stream — corrupt or truncated embedded asset, or a build/replace directive that swapped the binary for non-gzip bytes.","commonSituations":"Custom builds where the go:embed asset was overwritten or partially copied; a modified/stubbed challenge.go from a fork or a bad patch; binary corruption after a failed build or aggressive link stripping.","solutions":["Rebuild the binary from a clean checkout: git status / git checkout -- pkg/appsec/challenge and run make build again.","Verify the embedded asset is valid gzip (check the go:embed directive and any generation script that produces obfuscatorWasmGz).","Regenerate obfuscatorWasmGz with the project's own embed/generation tooling instead of hand-crafting the bytes.","If using a fork or patch, re-apply upstream changes to challenge.go and its embedded assets."],"exampleFix":"// before (hand-replaced asset)\nobfuscatorWasmGz = somePlainWasmBytes\n// after (regenerate properly and rebuild)\n// go:embed obfuscator.wasm.gz\nvar obfuscatorWasmGz []byte // produced by gzip of obfuscator.wasm via the build script","handlingStrategy":"try-catch","validationCode":"// Go: verify the embedded asset is valid gzip before initializing\nif _, err := gzip.NewReader(bytes.NewReader(obfuscatorWasmGz)); err != nil {\n    return fmt.Errorf(\"embedded obfuscator wasm is not valid gzip: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err != nil { return nil, fmt.Errorf(\"failed to create gzip reader for obfuscator wasm: %w\", err) } // check wrapped cause with errors.Unwrap","preventionTips":["Never hand-edit embedded binary assets; always generate via the build script","Add a unit test that gzip-opens obfuscatorWasmGz at package init/test time","Verify build artifact checksums in CI"],"tags":["go","wasm","gzip","embedded-assets"],"backgroundTag":"checksum-mismatch","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}