{"record":{"id":"e3589b4c9ff8e378","repo":"crowdsecurity/crowdsec","slug":"failed-to-decompress-obfuscator-wasm-w","errorCode":null,"errorMessage":"failed to decompress obfuscator wasm: %w","messagePattern":"failed to decompress obfuscator wasm: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/appsec/challenge/challenge.go","lineNumber":324,"sourceCode":"// 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)\n\t}\n\n\treturn compiledMod, nil\n}\n\n// compilerSupported mimics the check performed by wazero for SSE4.1\n// We cannot rely in wazero on the wazero check, as it is used to choose whether to use the compiler or interpreter mode","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/challenge.go#L306-L342","documentation":"This error is returned by compileObfuscatorModule when io.ReadAll on the gzip reader of the embedded obfuscator WASM fails mid-stream. The gzip header was valid but the payload is truncated or corrupt. It is raised once (guarded by sync.Once) during NewChallengeRuntime.","triggerScenarios":"Calling NewChallengeRuntime/Configure when reading the decompressed obfuscatorWasmGz stream fails — truncated embedded asset, bit rot in the binary, or corrupted memory of the byte slice.","commonSituations":"Truncated binaries from interrupted downloads/deploys; corrupted embedded assets in a custom build; running a binary damaged by disk issues.","solutions":["Rebuild and redeploy the crowdsec binary from a clean source tree (make build).","Compare the deployed binary checksum with a freshly built one to confirm corruption.","Regenerate the embedded obfuscator wasm asset with the project build tooling.","If reproducible in a clean build, report upstream with the wrapped gzip error."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Decompress fully in a test to detect truncation\nif _, err := io.ReadAll(mustGzipReader(obfuscatorWasmGz)); err != nil {\n    t.Fatalf(\"embedded wasm truncated: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := io.ReadAll(zr); err != nil { return fmt.Errorf(\"failed to decompress obfuscator wasm: %w\", err) }","preventionTips":["Compare deployed binary checksums against CI artifacts after deploys","Add a test decompressing the embedded wasm end-to-end","Avoid post-build binary mangling (strip/patch scripts that can truncate)"],"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-14T00:17:10.932Z"}