{"record":{"id":"0d8527d775b911d9","repo":"nats-io/nats-server","slug":"short-write-on-body-d-d-0d8527","errorCode":null,"errorMessage":"short write on body (%d != %d)","messagePattern":"short write on body \\((.+?) != (.+?)\\)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/ocsp_responsecache.go","lineNumber":352,"sourceCode":"\t\tcase ocsp.Good:\n\t\t\tc.stats.Goods++\n\t\tcase ocsp.Revoked:\n\t\t\tc.stats.Revokes++\n\t\tcase ocsp.Unknown:\n\t\t\tc.stats.Unknowns++\n\t\t}\n\t}\n}\n\nfunc (c *LocalCache) Compress(buf []byte) ([]byte, error) {\n\tbodyLen := int64(len(buf))\n\tvar output bytes.Buffer\n\twriter := s2.NewWriter(&output)\n\tinput := bytes.NewReader(buf[:bodyLen])\n\tif n, err := io.CopyN(writer, input, bodyLen); err != nil {\n\t\treturn nil, fmt.Errorf(certidp.ErrCannotWriteCompressed, err)\n\t} else if n != bodyLen {\n\t\treturn nil, fmt.Errorf(certidp.ErrTruncatedWrite, n, bodyLen)\n\t}\n\tif err := writer.Close(); err != nil {\n\t\treturn nil, fmt.Errorf(certidp.ErrCannotCloseWriter, err)\n\t}\n\treturn output.Bytes(), nil\n}\n\nfunc (c *LocalCache) Decompress(buf []byte) ([]byte, error) {\n\tbodyLen := int64(len(buf))\n\tinput := bytes.NewReader(buf[:bodyLen])\n\treader := io.NopCloser(s2.NewReader(input))\n\toutput, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(certidp.ErrCannotReadCompressed, err)\n\t}\n\treturn output, reader.Close()\n}\n","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/ocsp_responsecache.go#L334-L370","documentation":"This error is thrown by LocalCache.Compress in server/ocsp_responsecache.go when the s2 (Snappy) compression writer consumed fewer bytes than the full body length during io.CopyN. It means the OCSP response body was not fully written into the compression buffer, producing a truncated compressed record. The library throws it to prevent storing a silently corrupt cache entry.","triggerScenarios":"Calling LocalCache.Put on an OCSP response where the input reader (bytes.NewReader over buf[:bodyLen]) yields fewer bytes than bodyLen, or the s2 writer errors partway through the copy so io.CopyN returns n < bodyLen.","commonSituations":"A buffer whose declared bodyLen exceeds the data actually read from the OCSP responder response; a slice mismatch after partial reads; s2 writer returning a short write under memory pressure.","solutions":["Log n and bodyLen and inspect the buffer passed to Put; ensure buf[:bodyLen] actually contains bodyLen bytes.","Verify the upstream read that produced buf filled it completely before calling Put.","Replace the short-write path with io.Copy into the writer and check the writer's error instead of assuming bodyLen.","If persistent, bypass compression (store uncompressed) or regenerate the OCSP response and retry Put."],"exampleFix":"// before\nif n, err := io.CopyN(writer, input, bodyLen); err != nil {\n\treturn nil, fmt.Errorf(certidp.ErrCannotWriteCompressed, err)\n} else if n != bodyLen {\n\treturn nil, fmt.Errorf(certidp.ErrTruncatedWrite, n, bodyLen)\n}\n// after\nif n, err := io.CopyN(writer, input, bodyLen); err != nil {\n\treturn nil, fmt.Errorf(certidp.ErrCannotWriteCompressed, err)\n} else if n != bodyLen {\n\t// fall back to storing the raw response rather than a truncated record\n\treturn buf, nil\n}","handlingStrategy":"validation","validationCode":"// before calling Put\nif int64(len(buf)) < bodyLen {\n\treturn fmt.Errorf(\"buffer too small: have %d, need %d\", len(buf), bodyLen)\n}","typeGuard":"func isCompleteBody(buf []byte, bodyLen int64) bool {\n\treturn int64(len(buf)) >= bodyLen\n}","tryCatchPattern":null,"preventionTips":["Always fully read the OCSP response into buf before Put.","Assert len(buf) >= bodyLen before compressing.","Never reuse a partially-filled buffer across Put calls."],"tags":["compression","io","cache","ocsp"],"backgroundTag":"short-write","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}