gofr-dev/gofr · error

failed to create reader

Error message

failed to create reader

What it means

errFailedToCreateReader is returned by NewReader and NewRangeReader when the adapter cannot open a read stream for the object — typically the underlying ftp client's Retr/RetrFrom call failed. The sentinel may wrap the transport-level cause, which usually indicates the file does not exist, permissions deny access, or the connection is broken.

Source

Thrown at pkg/gofr/datasource/file/ftp/storage_adapter.go:25

	"fmt"
	"io"
	"path"
	"strings"
	"time"

	"github.com/jlaffaye/ftp"
	"gofr.dev/pkg/gofr/datasource/file"
)

var (
	// Storage adapter errors.
	errFTPConfigNil            = errors.New("FTP config is nil")
	errFTPClientNotInitialized = errors.New("FTP client is not initialized")
	errEmptyObjectName         = errors.New("object name is empty")
	errInvalidOffset           = errors.New("invalid offset: must be >= 0")
	errEmptySourceOrDest       = errors.New("source and destination names cannot be empty")
	errSameSourceAndDest       = errors.New("source and destination are the same")
	errFailedToCreateReader    = errors.New("failed to create reader")
	errFailedToCreateWriter    = errors.New("failed to create writer")
	errObjectNotFound          = errors.New("object not found")
	errFailedToGetObjectAttrs  = errors.New("failed to get object attrs")
	errFailedToDeleteObject    = errors.New("failed to delete object")
	errFailedToListObjects     = errors.New("failed to list objects")
	errFailedToListDirectory   = errors.New("failed to list directory")
	errWriterAlreadyClosed     = errors.New("writer already closed")
	errFTPConfigInvalid        = errors.New("invalid FTP configuration: host and port are required")
)

// Config represents the FTP configuration.
type Config struct {
	Host        string        // FTP server hostname
	User        string        // FTP username
	Password    string        // FTP password
	Port        int           // FTP port
	RemoteDir   string        // Remote directory path. Base Path for all FTP Operations.
	DialTimeout time.Duration // FTP connection timeout

View on GitHub (pinned to 187eb24962)

Solutions

  1. Verify the object exists (StatObject) and the path/remote dir is correct before reading.
  2. Check FTP credentials and file permissions on the server.
  3. Reconnect (fs.Connect) if the connection dropped, then retry the read.
  4. Inspect the wrapped cause (errors.Unwrap / provider logs) for the server's FTP response code.

Example fix

// before
r, err := adapter.NewReader(ctx, name)
// after
if _, err := adapter.StatObject(ctx, name); err != nil {
    return nil, fmt.Errorf("object %q unavailable: %w", name, err)
}
r, err := adapter.NewReader(ctx, name)
Defensive patterns

Strategy: retry

Validate before calling

if _, err := adapter.StatObject(ctx, name); err != nil {
    return fmt.Errorf("object %q not available for read: %w", name, err)
}
if !fsConnected() { reconnectFTP() }

Try / catch

r, err := adapter.NewReader(ctx, name)
if errors.Is(err, errFailedToCreateReader) {
    reconnectFTP()
    r, err = adapter.NewReader(ctx, name) // one retry after reconnect
    if err != nil { return fmt.Errorf("read %q failed after retry: %w", name, err) }
}

Prevention

When it happens

Trigger: NewReader/NewRangeReader on a nonexistent remote file, a file without read permission, or while the FTP connection has dropped mid-operation.

Common situations: Typos or wrong remote dir in the path; file deleted between listing and read; passive-mode/firewall issues killing the data connection; server-side 550 (file unavailable) responses.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/c1f4b62d8ba29b1e. Report an issue: GitHub.