gofr-dev/gofr · error

failed to create writer

Error message

failed to create writer

What it means

errFailedToCreateWriter is returned when the FTP storage adapter cannot open an STOR/APPE upload session for an object (NewWriter/Close path on the writer). It wraps the underlying goftp error that occurred while initiating the transfer. It indicates the server refused or failed to start the write operation.

Source

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

	"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 target directory exists and create it (MkdirAll) before creating the writer
  2. Check the FTP user's write permissions on the remote directory
  3. Confirm the underlying FTP connection is alive; reconnect via Connect if it dropped
  4. Inspect the wrapped error (errors.Unwrap) for the raw server reply to pinpoint the cause

Example fix

// before
w, err := fs.NewWriter(ctx, "uploads/data.csv", nil) // uploads/ may not exist
// after
_ = fs.MkdirAll(ctx, "uploads")
w, err := fs.NewWriter(ctx, "uploads/data.csv", nil)
if err != nil { return fmt.Errorf("create writer: %w", err) }
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure parent dir exists and connection is up before writing
if err := fs.MkdirAll(ctx, filepath.Dir(objectName)); err != nil { return err }
if err := fs.TestConnection(ctx); err != nil { return err }

Type guard

func isCreateWriterError(err error) bool { return errors.Is(err, ftp.ErrFailedToCreateWriter) }

Try / catch

w, err := fs.NewWriter(ctx, name, nil)
if err != nil {
    if errors.Is(err, ftp.ErrFailedToCreateWriter) {
        // check dir/permissions/reconnect, then retry once with a new writer
    }
    return err
}

Prevention

When it happens

Trigger: Calling NewWriter (or Create) on the FTP filesystem when the remote directory does not exist, permissions deny upload, the data connection cannot be opened, or the connection has dropped.

Common situations: Uploading to a path whose parent directory was never created; FTP user lacks write permission on the target directory; passive-mode firewall blocking the data channel; server hit disk quota or connection limit.

Related errors


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