{"record":{"id":"f015449860bbfdc4","repo":"nats-io/nats-server","slug":"error-writing-to-compression-writer-w","errorCode":null,"errorMessage":"error writing to compression writer: %w","messagePattern":"error writing to compression writer: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/filestore.go","lineNumber":14521,"sourceCode":"\tbodyLen := int64(len(buf) - checksumSize)\n\tvar output bytes.Buffer\n\tvar writer io.WriteCloser\n\tswitch alg {\n\tcase NoCompression:\n\t\treturn buf, nil\n\tcase S2Compression:\n\t\twriter = s2.NewWriter(&output)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"compression algorithm not known\")\n\t}\n\n\tinput := bytes.NewReader(buf[:bodyLen])\n\tchecksum := buf[bodyLen:]\n\n\t// Compress the block content, but don't compress the checksum.\n\t// We will preserve it at the end of the block as-is.\n\tif n, err := io.CopyN(writer, input, bodyLen); err != nil {\n\t\treturn nil, fmt.Errorf(\"error writing to compression writer: %w\", err)\n\t} else if n != bodyLen {\n\t\treturn nil, fmt.Errorf(\"short write on body (%d != %d)\", n, bodyLen)\n\t}\n\tif err := writer.Close(); err != nil {\n\t\treturn nil, fmt.Errorf(\"error closing compression writer: %w\", err)\n\t}\n\n\t// Now add the checksum back onto the end of the block.\n\tif n, err := output.Write(checksum); err != nil {\n\t\treturn nil, fmt.Errorf(\"error writing checksum: %w\", err)\n\t} else if n != checksumSize {\n\t\treturn nil, fmt.Errorf(\"short write on checksum (%d != %d)\", n, checksumSize)\n\t}\n\n\treturn output.Bytes(), nil\n}\n\nfunc (alg StoreCompression) Decompress(buf []byte) ([]byte, error) {","sourceCodeStart":14503,"sourceCodeEnd":14539,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L14503-L14539","documentation":"During Compress(), io.CopyN streams the block body into the s2 writer; if the copy reports an error, the underlying write failed and the block cannot be produced, so the error is wrapped with \"error writing to compression writer: %w\". From server/filestore.go.","triggerScenarios":"io.CopyN returns err != nil while compressing a block body — e.g. the s2 writer's internal buffer flush fails on the underlying bytes.Buffer (allocation failure) or the input reader fails early.","commonSituations":"Out-of-memory / allocation pressure making the output buffer fail; programming error passing a nil or closed writer; extremely large blocks stressing memory limits.","solutions":["Inspect the wrapped %w cause to find the underlying writer failure","Retry the compression once with a fresh output buffer (transient memory pressure)","Reduce block size to lower peak compression memory usage","If persistent, check host memory limits and disable compression (NoCompression) as a fallback"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"null","typeGuard":null,"tryCatchPattern":"out, err := alg.Compress(block)\nif err != nil {\n\tvar werr error\n\tif strings.Contains(err.Error(), \"error writing to compression writer\") {\n\t\t// unwrap: retry once with fresh buffer, then fall back to NoCompression\n\t\twerr = retryCompressOrNoop(block)\n\t}\n\t_ = werr\n\treturn err\n}","preventionTips":["Check host memory limits for large blocks","Keep block sizes bounded to cap compression memory","Retry compression once on transient failures","Have a NoCompression fallback path for writes"],"tags":["jetstream","filestore","compression","io"],"backgroundTag":"compression-write-failed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}