{"record":{"id":"b964aff4ca16fb8e","repo":"gofr-dev/gofr","slug":"s3-backend-did-not-honor-the-requested-byte-range","errorCode":null,"errorMessage":"s3 backend did not honor the requested byte range","messagePattern":"s3 backend did not honor the requested byte range","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/datasource/file/s3/file.go","lineNumber":45,"sourceCode":"\tlogger       Logger\n\tmetrics      Metrics\n\tsize         int64\n\tcontentType  string\n\tbody         io.ReadCloser\n\tlastModified time.Time\n}\n\nfunc (*S3File) Sys() any {\n\treturn nil\n}\n\nvar (\n\tErrNilResponse = errors.New(\"response retrieved is nil \")\n\t// ErrRangeNotHonored is returned when a byte-range read was requested but the\n\t// backend answered with the whole object (no Content-Range header). Filling the\n\t// caller's buffer from byte 0 in that case would silently serve the wrong bytes,\n\t// so the read is refused instead.\n\tErrRangeNotHonored = errors.New(\"s3 backend did not honor the requested byte range\")\n)\n\n// Close closes the response body returned in Open/Create methods if the response body is not nil.\nfunc (f *S3File) Close() error {\n\tbucketName := getBucketName(f.name)\n\n\tdefer f.sendOperationStats(&FileLog{\n\t\tOperation: \"CLOSE\",\n\t\tLocation:  getLocation(bucketName)}, time.Now())\n\n\tif f.body != nil {\n\t\treturn f.body.Close()\n\t}\n\n\treturn nil\n}\n\n// closeBody closes a previously opened response body (if any) before it is","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/datasource/file/s3/file.go#L27-L63","documentation":"ErrRangeNotHonored is returned by Read/ReadAt when a byte-range GetObject request was sent (offset > 0) but the backend replied with the whole object and no Content-Range header. Accepting such a response would fill the caller's buffer starting at byte 0, silently serving wrong bytes, so the library refuses the read. It almost always indicates an S3-compatible backend that ignores Range headers.","triggerScenarios":"1) (*S3File).Read with f.offset > 0 while res.ContentRange == nil; 2) (*S3File).ReadAt (which always sends a Range header) against a backend that ignores it. Both wrap nothing — the sentinel is returned directly.","commonSituations":"Using MinIO, Ceph, mock S3 servers, or caching proxies that ignore the Range header; serving reads after Seek pushed the offset past 0; test double S3 clients that return a full body without ContentRange.","solutions":["Verify the backend honors Range requests: aws s3api get-object --range bytes=10- ... and check the Content-Range response header.","Replace or reconfigure the non-conformant S3-compatible storage/proxy (MinIO/Ceph/nginx caching layer) so Range is honored.","In tests, make the fake GetObject implementation return ContentRange (e.g. aws.String(\"bytes 10-99/100\")) whenever a Range input is present.","As a workaround, Seek back to 0 and read the whole object sequentially, since offset 0 sends no Range header."],"exampleFix":"// test mock that triggers the error\nres := &s3.GetObjectOutput{Body: body} // no ContentRange\n// after\nres := &s3.GetObjectOutput{Body: body, ContentRange: aws.String(fmt.Sprintf(\"bytes %d-%d/%d\", off, total-1, total))}","handlingStrategy":"fallback","validationCode":"// probe backend range support once at startup:\nout, err := client.GetObject(ctx, &s3.GetObjectInput{Bucket: b, Key: k, Range: aws.String(\"bytes=0-0\")})\nrangeOK := err == nil && out.ContentRange != nil","typeGuard":null,"tryCatchPattern":"n, err := f.Read(buf)\nif errors.Is(err, s3datasource.ErrRangeNotHonored) {\n    // fallback: seek to 0 and stream the whole object sequentially\n    f.Seek(0, io.SeekStart)\n    return f.Read(buf)\n}","preventionTips":["Verify Range/Content-Range support of your S3-compatible store before enabling offset reads.","Disable middle-box caching that strips Range handling.","Make test doubles return ContentRange when given a Range input.","Prefer full sequential reads on backends known to ignore Range."],"tags":["s3","http-range","s3-compatible","gofr"],"backgroundTag":"range-request-not-honored","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}