# FTP and FTPS

> The ftp destination: FTP and explicit FTPS.

FTP and FTPS servers: the `ftp` destination, from the `ftp` package. Declare the package once in `dependencies.yml`; DRE installs it on demand:

dependencies.yml

```yaml
plugins:
  - ftp
```

### Profile fields

Set in `profiles.yml`, under `destinations:`, in a target with `type: ftp`.

Field

Default

Notes

`host` (required)

FTP server.

`port`

`21`

Port.

`username` (required)

User name.

`password`

Password. Secret: use `env_var()`.

`tls`

`none`

None or explicit (FTPS) One of `none`, `explicit`.

`passive`

Passive mode (default true)

`tls_accept_invalid_certs`

Accept a self-signed server certificate.

`connect_timeout`

`30s`

How long to wait for a connection (`30s`, `2m`, or seconds) A duration (`30s`, `2m`) or seconds.

`timeout`

`60s`

How long a read or write may make no progress before it fails. A duration (`30s`, `2m`) or seconds.

`retries`

`3`

How many times to try again after a temporary error (0: never)

### Options

Set in the report’s `output.destination` entry.

Option

Type

Default

Notes

`if_exists`

string

`overwrite`

When a file is already at the path: `overwrite` it, fail with `error`, or `number` the new one. One of `overwrite`, `error`, `number`.

`atomic`

boolean

`true`

Upload under a temporary name, then rename, so no half-written file appears.

`temp_dir`

string

Where the temporary file goes (on the same server), for receivers that pick up any new file.

## Notes

`host`, `port` (21), `username`, `password`, `passive` (default true), and `tls`: `none` or `explicit` (FTPS). `tls_accept_invalid_certs` allows self-signed server certificates.

Paths are relative to the folder the login starts in; a leading `/` means the server’s root, which on many servers isn’t the login folder (`/reports/x.csv` vs `reports/x.csv`). FTPS data connections reuse the control connection’s TLS session, which vsftpd, ProFTPD and FileZilla Server require by default. Uploads go under a temporary name first (`atomic`, `temp_dir`: see [Uploads under a temporary name](https://getdre.com/docs/plugins/#uploads-under-a-temporary-name)), and a failed upload removes the temporary file from the server when it can. With `if_exists: error` or `number`, DRE looks for the name before the rename; FTP can’t do both in one step (see [A file already at the path](https://getdre.com/docs/plugins/#a-file-already-at-the-path)).

## Send an export over explicit FTPS

Use FTP when the receiver requires it; explicit FTPS protects the connection. Adapt the report in the [SFTP delivery example](https://github.com/get-dre/dre/blob/v0.5.1/examples/sftp-delivery/) with the `ftp` package and:

profiles.yml

```yaml
destinations:
  partner:
    targets:
      dev: {deliver: false}
      prod:
        type: ftp
        host: ftp.example.com
        username: reporting
        password: "{{ env_var('DRE_SECRET_FTP_PASSWORD') }}"
        tls: explicit
        passive: true
```

```yaml
# within the report's output
destination:
  profile: partner
  path: "incoming/report-{{ run.date.yyyymmdd }}.csv"
  atomic: true
  temp_dir: staging
  if_exists: error
```

Keep `tls_accept_invalid_certs` disabled for a real server. A certificate failure needs the server certificate or trust chain repaired. `ftp/file-exists` means the name is taken; `delivery-failed` on rename needs write access in both directories and a supported rename. For a firewall timeout, check passive data ports as well as the control port. See [destination keys](https://getdre.com/docs/reference-report/#outputdestination), [atomic uploads](https://getdre.com/docs/plugins/#uploads-under-a-temporary-name) and [destination](https://getdre.com/docs/glossary/#destination).

[Edit page](https://github.com/get-dre/dre/edit/master/docs/plugin-ftp.md)

[Previous  
SFTP](https://getdre.com/docs/plugin-sftp/)[Next  
Email](https://getdre.com/docs/plugin-email/)
