gofr-dev/gofr · error
response retrieved is nil
Error message
response retrieved is nil
What it means
ErrNilResponse is the sentinel error of the GoFr S3 file datasource reported when a GetObject call succeeds at the HTTP level but the returned response body is nil, so there is no data stream to read from. It is wrapped by Read as '%w: S3 file is empty', meaning the S3 object could not be materialized into a readable body. This is a defensive check against SDK/proxy anomalies rather than a normal user error.
Source
Thrown at pkg/gofr/datasource/file/s3/file.go:40
//nolint:revive // s3.S3File is repetitive. A better name could have been chosen, but it's too late as it's already exported.
type S3File struct {
conn s3Client
name string
offset int64
logger Logger
metrics Metrics
size int64
contentType string
body io.ReadCloser
lastModified time.Time
}
func (*S3File) Sys() any {
return nil
}
var (
ErrNilResponse = errors.New("response retrieved is nil ")
// ErrRangeNotHonored is returned when a byte-range read was requested but the
// backend answered with the whole object (no Content-Range header). Filling the
// caller's buffer from byte 0 in that case would silently serve the wrong bytes,
// so the read is refused instead.
ErrRangeNotHonored = errors.New("s3 backend did not honor the requested byte range")
)
// Close closes the response body returned in Open/Create methods if the response body is not nil.
func (f *S3File) Close() error {
bucketName := getBucketName(f.name)
defer f.sendOperationStats(&FileLog{
Operation: "CLOSE",
Location: getLocation(bucketName)}, time.Now())
if f.body != nil {
return f.body.Close()
}View on GitHub (pinned to 187eb24962)
Solutions
- Check that the target S3-compatible backend actually returns a body stream for GetObject (curl/S3 console or aws s3 cp the object to confirm it is retrievable).
- Upgrade github.com/aws/aws-sdk-go-v2 and the gofr module to latest versions to rule out SDK field-contract changes.
- If using a mock S3 client, populate GetObjectOutput.Body (e.g. io.NopCloser(bytes.NewReader(data))) instead of returning an empty struct.
- Handle the error with errors.Is(err, s3.ErrNilResponse) and treat it as a failed/retryable read rather than nil-data.
Example fix
// before: mock returns empty output
res := &s3.GetObjectOutput{}
// after
res := &s3.GetObjectOutput{Body: io.NopCloser(bytes.NewReader(objBytes))} Defensive patterns
Strategy: try-catch
Validate before calling
// no pre-call validation possible; ensure backend/mocks supply a Body
// when stubbing:
// out := &s3.GetObjectOutput{Body: io.NopCloser(bytes.NewReader(data))} Try / catch
n, err := f.Read(buf)
if err != nil {
if errors.Is(err, s3datasource.ErrNilResponse) {
// backend returned no body: fail fast or retry once
}
return err
} Prevention
- Use conformant S3 backends (real S3, recent MinIO).
- Always populate Body in mocked GetObjectOutput.
- Keep aws-sdk-go-v2 and gofr versions current.
- Wrap reads with errors.Is checks for sentinel errors.
When it happens
Trigger: Calling (*S3File).Read when the underlying s3.GetObjectOutput has a nil Body — e.g. an S3-compatible backend (MinIO, mock, or misbehaving proxy) returns a 200 with no body stream, or a test/mock client returns an output struct without Body.
Common situations: Pointing the datasource at non-AWS S3-compatible stores that don't fully honor the GetObject contract; using fake/mocked AWS clients in tests that forget Body; SDK version mismatches where output struct fields change.
Related errors
- %w: S3 file is empty
- s3 backend did not honor the requested byte range
- %w: negative offset %d
- out of range
- incorrect file type
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/6909484b0056d0d6.
Report an issue: GitHub.