> ## Documentation Index
> Fetch the complete documentation index at: https://doc.lucidworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# FTP Pro

> The FTP Pro connector retrieves documents using the File Transfer Protocol (FTP), FTPS, and SFTP.

export const schema = {
  "type": "object",
  "title": "FTP Pro",
  "description": "A connector that fetches content from a FTP/FTPS/SFTP server",
  "required": ["id", "properties", "pipeline"],
  "properties": {
    "id": {
      "type": "string",
      "title": "Configuration ID",
      "description": "A unique identifier for this Configuration.",
      "minLength": 1,
      "pattern": "^[a-zA-Z0-9_-]+$"
    },
    "pipeline": {
      "type": "string",
      "title": "Pipeline ID",
      "description": "Name of the IndexPipeline used for processing output.",
      "minLength": 1,
      "pattern": "^[a-zA-Z0-9_-]+$"
    },
    "parserId": {
      "type": "string",
      "title": "Parser ID",
      "description": "The Parser to use in the associated IndexPipeline.",
      "pattern": "^[a-zA-Z0-9_-]+$"
    },
    "description": {
      "type": "string",
      "title": "Description",
      "description": "Optional description",
      "hints": ["lengthy"],
      "maxLength": 125
    },
    "created": {
      "type": "string",
      "title": "Date Created",
      "description": "The date at which this Configuration was created.",
      "hints": ["readonly", "hidden"]
    },
    "type": {
      "type": "string",
      "title": "Type",
      "description": "A type ID for this connector.",
      "hints": ["readonly", "hidden"]
    },
    "modified": {
      "type": "string",
      "title": "Date Modified",
      "description": "The date at which this Configuration was last modified.",
      "hints": ["readonly", "hidden"]
    },
    "collection": {
      "type": "string",
      "title": "Collection ID",
      "description": "The associated content Collection.",
      "hints": ["readonly", "hidden"],
      "minLength": 1,
      "pattern": "^[a-zA-Z0-9_-]+$"
    },
    "diagnosticLogging": {
      "type": "boolean",
      "title": "Diagnostic Logging",
      "description": "[Deprecated] Enables verbose diagnostic logging for troubleshooting. May increase log volume. Disabled by default.",
      "default": false
    },
    "type_description": {
      "type": "string",
      "title": "Type Description",
      "default": "A connector that fetches content from a FTP/FTPS/SFTP server",
      "hints": ["hidden", "readonly"]
    },
    "category": {
      "type": "string",
      "title": "Category",
      "default": "A connector that fetches content from a FTP/FTPS/SFTP server",
      "hints": ["hidden", "readonly"]
    },
    "connector": {
      "title": "Connector Type",
      "description": "Connector type.",
      "minLength": 1,
      "type": "string",
      "hints": ["hidden"]
    },
    "properties": {
      "type": "object",
      "title": "FTP properties",
      "description": "Plugin specific properties.",
      "required": ["server", "authentication"],
      "properties": {
        "server": {
          "type": "object",
          "title": "Server Properties ",
          "description": "Settings to connect to the server",
          "required": ["port", "host", "protocols"],
          "properties": {
            "protocols": {
              "type": "string",
              "title": "Protocol",
              "description": "Protocol types allowed:  FTP, FTPS and SFTP",
              "enum": ["FTP", "FTPS", "SFTP"],
              "default": "FTP"
            },
            "host": {
              "type": "string",
              "title": "Hostname",
              "description": "The Server Hostname",
              "default": "127.0.0.1"
            },
            "port": {
              "type": "number",
              "title": "Port",
              "description": "The Server port. Use 21 for FTP/FTPS (default). Use 22 for SFTP.",
              "default": 21,
              "maximum": 2147483647,
              "exclusiveMaximum": false,
              "minimum": -2147483648,
              "exclusiveMinimum": false,
              "multipleOf": 1
            }
          }
        },
        "sftp": {
          "type": "object",
          "title": "SFTP Properties",
          "description": "SFTP-specific settings (only applicable when protocol is SFTP)",
          "required": [],
          "properties": {
            "trustedHostKey": {
              "type": "string",
              "title": "Trusted SSH Host Key Fingerprint",
              "description": "SSH host key fingerprint to verify server identity. Supports MD5 (MD5:xx:xx:...) and SHA256 (SHA256:xxx...) formats. If empty, verification is disabled (not recommended for production). Get fingerprint: ssh-keyscan hostname | ssh-keygen -E md5 -lf -",
              "hints": ["secret"]
            }
          }
        },
        "authentication": {
          "type": "object",
          "title": "Authentication Methods",
          "description": "Authentication method used to connect to the server. If none authentication method is selected, the connector will attempt anonymous login for FTP/FTPS connections",
          "required": [],
          "properties": {
            "username": {
              "type": "string",
              "title": "Username",
              "description": "Username to authenticate to the FTP/FTPS/SFTP server. Leave empty for anonymous FTP/FTPS login."
            },
            "passwordAuth": {
              "type": "object",
              "title": "Password Authentication",
              "description": "Supported for all protocols. Leave empty for anonymous login with FTP/FTPS.",
              "required": [],
              "properties": {
                "password": {
                  "type": "string",
                  "title": "Password",
                  "description": "Password associated with the username. This value is stored as a secret.",
                  "hints": ["secret"]
                }
              }
            },
            "publicKeyAuth": {
              "type": "object",
              "title": "SSH Public Key Authentication",
              "description": "SSH key-based authentication for SFTP. Provide private key (with optional passphrase).",
              "required": ["privateKey"],
              "properties": {
                "privateKey": {
                  "type": "string",
                  "title": "SSH Private Key",
                  "description": "SSH private key for authentication (PEM format). Supports RSA, DSA, ECDSA, and Ed25519 keys. This value is stored as a secret.",
                  "hints": ["secret"]
                },
                "passphrase": {
                  "type": "string",
                  "title": "Passphrase",
                  "description": "Optional passphrase to decrypt the private key if it is encrypted. Leave empty if the private key is not encrypted. This value is stored as a secret.",
                  "hints": ["secret"]
                }
              }
            }
          }
        },
        "paths": {
          "type": "array",
          "title": "Paths",
          "description": "List of directory or file paths to retrieve.\nIf empty, the crawl will start from the root directory (/).",
          "items": {
            "type": "string"
          }
        },
        "limitDocument": {
          "type": "object",
          "title": "Limit Documents Properties",
          "description": "Documents filtering options",
          "required": [],
          "properties": {
            "includeDirectories": {
              "type": "boolean",
              "title": "Index Directories",
              "description": "When true, directories (folders) are indexed as documents with its metadata.",
              "default": false
            },
            "addFailedDocs": {
              "type": "boolean",
              "title": "Index Failed Documents",
              "description": "When true, failed documents are indexed as documents with its metadata, without content",
              "default": false
            },
            "maxDepth": {
              "type": "number",
              "title": "Maximum Level Depth",
              "description": "Specifies the maximum number of levels in a folder to descend for documents. When set to a positive value, folders whose level depth exceeds this limit will not be fetched. The default (0) means 'no limit', all folder levels will be traversed.",
              "default": 0,
              "maximum": 2147483647,
              "exclusiveMaximum": false,
              "minimum": 0,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "includedFileExtensions": {
              "type": "array",
              "title": "Included file extensions",
              "description": "Set of file extensions to be fetched. If specified, all non-matching files will be skipped.",
              "default": [],
              "items": {
                "type": "string",
                "minLength": 1
              }
            },
            "excludedFileExtensions": {
              "type": "array",
              "title": "Excluded file extensions",
              "description": "A set of all file extensions to be skipped from the fetch.",
              "default": [],
              "items": {
                "type": "string",
                "minLength": 1
              }
            },
            "inclusiveRegexes": {
              "type": "array",
              "title": "Inclusive regexes",
              "description": "Regular expressions for path patterns to include. This will limit this datasource to only paths that match the regular expression.",
              "default": [],
              "items": {
                "type": "string",
                "minLength": 1
              }
            },
            "exclusiveRegexes": {
              "type": "array",
              "title": "Exclusive regexes",
              "description": "Regular expressions for path patterns to exclude. This will limit this datasource to only paths that do not match the regular expression.",
              "default": [],
              "items": {
                "type": "string",
                "minLength": 1
              }
            },
            "maxSizeBytes": {
              "type": "number",
              "title": "Maximum File Size",
              "description": "Specifies the maximum file size for content download (bytes). When set to a positive value, files exceeding this limit will be indexed with metadata only, with exclusion reason in '_lw_contents_excluded_s'. The default (0) means 'no maximum size' - all file contents will be downloaded.",
              "default": 0,
              "maximum": 2147483647,
              "exclusiveMaximum": false,
              "minimum": 0,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "minSizeBytes": {
              "type": "number",
              "title": "Minimum File Size",
              "description": "Specifies the minimum file size for content download (bytes). When set to a positive value, files below this limit will be indexed with metadata only, with exclusion reason in '_lw_contents_excluded_s'. The default (0) means 'no minimum size' - all file contents will be downloaded.",
              "default": 0,
              "maximum": 2147483647,
              "exclusiveMaximum": false,
              "minimum": 0,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "regexCacheSize": {
              "type": "number",
              "title": "",
              "default": 10000,
              "hints": ["hidden"],
              "maximum": 2147483647,
              "exclusiveMaximum": false,
              "minimum": -2147483648,
              "exclusiveMinimum": false,
              "multipleOf": 1
            }
          }
        },
        "connection": {
          "type": "object",
          "title": "Connection Properties",
          "description": "Connection options",
          "required": [],
          "properties": {
            "connectionTimeout": {
              "type": "number",
              "title": "Connection Timeout",
              "description": "Maximum time (in milliseconds) to establish a connection to the server",
              "default": 30000,
              "maximum": 300000,
              "exclusiveMaximum": false,
              "minimum": 1,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "dataTimeout": {
              "type": "number",
              "title": "Data Timeout",
              "description": "Maximum time (in milliseconds) to wait for a server response or data during operations",
              "default": 60000,
              "maximum": 900000,
              "exclusiveMaximum": false,
              "minimum": 1,
              "exclusiveMinimum": false,
              "multipleOf": 1
            }
          }
        },
        "retryProperties": {
          "type": "object",
          "title": "Retry Properties",
          "description": "Configure the retry behavior for failed requests.",
          "required": [],
          "properties": {
            "retryCount": {
              "type": "number",
              "title": "Retry Count",
              "description": "Number of attempts a request will be retried. Set to 0 to disable retrying.",
              "default": 3,
              "maximum": 36,
              "exclusiveMaximum": false,
              "minimum": 0,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "maxDelayTime": {
              "type": "number",
              "title": "Maximum Delay Time",
              "description": "The maximum wait time in milliseconds between retries.",
              "default": 60000,
              "maximum": 300000,
              "exclusiveMaximum": false,
              "minimum": 1000,
              "exclusiveMinimum": false,
              "multipleOf": 1
            }
          },
          "hints": ["advanced"]
        },
        "maximumItemLimitConfig": {
          "type": "object",
          "title": "Item Count Limits",
          "required": [],
          "properties": {
            "maxItems": {
              "type": "number",
              "title": "Maximum Output Limit",
              "description": "Limits the number of items emitted to the configured IndexPipeline. The default is no limit (-1).",
              "default": -1,
              "maximum": 2147483647,
              "exclusiveMaximum": false,
              "minimum": -2147483648,
              "exclusiveMinimum": false,
              "multipleOf": 1
            }
          }
        }
      }
    },
    "coreProperties": {
      "type": "object",
      "title": "Core Properties",
      "description": "Common behavior and performance settings.",
      "required": [],
      "properties": {
        "fetchSettings": {
          "type": "object",
          "title": "Fetch Settings",
          "description": "System level settings for controlling fetch behavior and performance.",
          "required": [],
          "properties": {
            "numFetchThreads": {
              "type": "number",
              "title": "Fetch Threads",
              "description": "Maximum number of fetch threads; defaults to 5.This setting controls the number of threads that call the Connectors fetch method.Higher values can, but not always, help with overall fetch performance.",
              "default": 5,
              "maximum": 500,
              "exclusiveMaximum": false,
              "minimum": 1,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "indexingThreads": {
              "type": "number",
              "title": "Index Subscription Threads",
              "description": "Maximum number of indexing threads; defaults to 4.This setting controls the number of threads in the indexing service used for processing content documents emitted by this datasource.Higher values can sometimes help with overall fetch performance.",
              "default": 4,
              "maximum": 10,
              "exclusiveMaximum": false,
              "minimum": 1,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "pluginInstances": {
              "type": "number",
              "title": "Number of plugin instances for distributed fetching",
              "description": "Maximum number of plugin instances for distributed fetching. Only specified number of plugin instanceswill do fetching. This is useful for distributing load between different instances.",
              "default": 0,
              "maximum": 500,
              "exclusiveMaximum": false,
              "minimum": 0,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "fetchItemQueueSize": {
              "type": "number",
              "title": "Fetch Item Queue Size",
              "description": "Size of the fetch item queue.Larger values result in increased memory usage, but potentially higher performance.Default is 10k.",
              "default": 10000,
              "hints": ["hidden"],
              "maximum": 500000,
              "exclusiveMaximum": false,
              "minimum": 1,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "fetchRequestCheckInterval": {
              "type": "number",
              "title": "Fetch request check interval(ms)",
              "description": "The amount of time to wait before check if a request is done",
              "default": 15000,
              "hints": ["hidden"],
              "maximum": 500000,
              "exclusiveMaximum": false,
              "minimum": 1000,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "fetchResponseScheduledTimeout": {
              "type": "number",
              "title": "Fetch response scheduled timeout(ms)",
              "description": "The maximum amount of time for a response to be scheduled. The task will be canceled if this setting is exceeded.",
              "default": 300000,
              "maximum": 500000,
              "exclusiveMaximum": false,
              "minimum": 1000,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "fetchResponseCompletedTimeout": {
              "type": "number",
              "title": "Fetch response completion timeout(ms)",
              "description": "The maximum amount of time for a response to be completed. If exceeded, the task will be retried if the job is still running",
              "default": 300000,
              "hints": ["hidden"],
              "maximum": 600000,
              "exclusiveMaximum": false,
              "minimum": 1,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "indexingInactivityTimeout": {
              "type": "number",
              "title": "Indexing inactivity timeout(seconds)",
              "description": "The maximum amount of time to wait for indexing results (in seconds). If exceeded, the job will fail with an indexing inactivity timeout.",
              "default": 86400,
              "maximum": 691200,
              "exclusiveMaximum": false,
              "minimum": 60,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "pluginInactivityTimeout": {
              "type": "number",
              "title": "Plugin inactivity timeout(seconds)",
              "description": "The maximum amount of time to wait for plugin activity (in seconds). If exceeded, the job will fail with a plugin inactivity timeout.",
              "default": 600,
              "maximum": 691200,
              "exclusiveMaximum": false,
              "minimum": 60,
              "exclusiveMinimum": false,
              "multipleOf": 1
            },
            "indexMetadata": {
              "type": "boolean",
              "title": "Index metadata",
              "description": "When enabled the metadata of skipped items will be indexed to the content collection.",
              "default": false
            },
            "indexContentFields": {
              "type": "boolean",
              "title": "Index content fields",
              "description": "When enabled, content fields will be indexed to the crawl-db collection.",
              "default": false
            },
            "asyncParsing": {
              "type": "boolean",
              "title": "Async Parsing",
              "description": "When enabled, content will be indexed asynchronously.",
              "default": false
            }
          }
        },
        "skipConfigValidation": {
          "type": "boolean",
          "title": "Skip Validation",
          "description": "Enable to skip configuration validation when it takes too long and causes timeout issue",
          "default": false
        }
      },
      "hints": ["advanced"]
    }
  },
  "category": "File System",
  "categoryPriority": 1
};

export const SchemaParamFields = ({schema}) => {
  const sanitize = str => {
    if (typeof str !== "string") return str;
    return str.replace(/^"(.*)"$/s, "$1").replace(/\\/g, "").replace(/"/g, "'");
  };
  const formatDescription = str => {
    const s = sanitize(str);
    return (/[.!?]\)*$/).test(s) ? s : `${s}.`;
  };
  const {description, properties = {}, required: requiredProps = []} = schema;
  const visibleProps = useMemo(() => Object.entries(properties).filter(([, prop]) => !prop.hints?.includes("hidden")), [properties]);
  return <div>
      {description && <p>{formatDescription(description)}</p>}

      {visibleProps.map(([name, prop]) => {
    const isRequired = requiredProps.includes(name);
    const hasDefault = prop.default !== undefined;
    const rawDefault = prop.default;
    const isComplexDefault = hasDefault && (typeof rawDefault === "object" || typeof rawDefault === "string" && (rawDefault.length > 20 || rawDefault.includes('"')));
    const fieldProps = {
      key: name,
      body: prop.title || name,
      type: prop.type,
      ...prop.title && ({
        post: [<><span className="text-stone-400 dark:text-stone-500">API property: </span>{name}</>]
      }),
      ...isRequired && ({
        required: true
      }),
      ...!isComplexDefault && hasDefault ? {
        default: sanitize(String(rawDefault))
      } : {}
    };
    const isObject = prop.type === "object" && prop.properties;
    const isArrayOfObjects = prop.type === "array" && prop.items?.type === "object" && prop.items.properties;
    return <ParamField {...fieldProps}>
            {prop.description && <p>{formatDescription(prop.description)}</p>}

            {isComplexDefault && <div className="flex">
                <p>
                  <strong>Default:</strong>
                </p>
                <pre className="!my-0">
                  <code>
                    {JSON.stringify(rawDefault, null, 2)}
                  </code>
                </pre>
              </div>}

            {isArrayOfObjects && <div className="flex">
              <p>
                <strong>Object attributes:</strong>
              </p>
              <pre className="!my-0">
                <code>
                  {'{\n'}
                  {Object.entries(prop.items.properties).map(([iname, iprop]) => <>
                      {`  ${iname}`}
                      {prop.items?.required?.includes(iname) && <span style={{
      color: 'red'
    }}> required</span>}
                      {`: {\n    display name: ${sanitize(iprop.title || '')}\n    type: ${iprop.type}\n  }\n`}
                    </>)}
                  {'}'}
                </code>
              </pre>
              </div>}

            {isObject && <Expandable title="properties">
                <SchemaParamFields schema={{
      properties: prop.properties,
      required: prop.required
    }} />
              </Expandable>}
          </ParamField>;
  })}
    </div>;
};

export const LwTemplate = ({title = "Key questions to get you started", icon = "sparkles", cta = "Powered by Agent Studio", linkHref = "https://lucidworks.com/demo/?utm_source=docs&utm_medium=referral&utm_campaign=docs_cta_ai"}) => {
  const [isLoaded, setIsLoaded] = useState(false);
  useEffect(() => {
    const timer = setTimeout(() => {
      setIsLoaded(true);
    }, 500);
    return () => clearTimeout(timer);
  }, []);
  return <div className="lw-template-container">
      <Card title={title} icon={icon}>
        {isLoaded && <span dangerouslySetInnerHTML={{
    __html: `<lw-template id="a029c1a9-28be-427e-b0e1-5d918920246a"></lw-template
            >`
  }} />}
        <Link href={linkHref} className="agent-studio-link text-left text-gray-600 gap-2 dark:text-gray-400 text-sm font-medium flex flex-row items-center hover:text-primary dark:hover:text-primary-light group-hover:text-primary group-hover:dark:text-primary-light">Powered by Lucidworks Agent Studio</Link>
      </Card>
    </div>;
};

<Callout icon="plug" color="#A4C6F7" iconType="solid">
  * **Latest version:** v1.0.0
  * **Compatible with Fusion version:** 5.9.0 and later
</Callout>

The FTP Pro connector retrieves documents using the File Transfer Protocol (FTP), FTP Secure (FTPS), and SSH File Transfer Protocol (SFTP). This modern connector replaces the legacy FTP connector with enhanced security, intelligent retry mechanisms, and advanced filtering capabilities.

Download this connector from the [V2 and Pro connectors download page](/docs/fusion-connectors/downloads/v2-connectors-downloads).

<LwTemplate />

## What are Pro connectors?

Pro connectors are built on the same framework as V2 connectors but meet higher internal standards for stability, reliability, and production readiness. If you’re currently using other V2 connectors, the process for installing and upgrading a Pro connector remains the same.

## Protocol support

The FTP Pro connector supports FTP, FTPS, and SFTP connections.

### FTP (File Transfer Protocol)

Standard unencrypted FTP connections. Use only for non-sensitive data or when connecting within a trusted network.

### FTPS (FTP Secure)

FTP over explicit SSL/TLS encryption. The connector supports explicit FTPS connections that upgrade a standard FTP connection to use encryption.

### SFTP (SSH File Transfer Protocol)

SSH-based file transfer protocol with built-in encryption. SFTP is the recommended protocol for secure file transfers and supports both password and public key authentication.

## Business use cases

If you rely on FTP due to third-party integrations, regulatory or compliance requirements, restricted environments, or legacy systems, the FTP Pro connector lets you index data from an FTP server to Fusion for a modern search experience.

<Tabs>
  <Tab title="Business-to-Consumer" icon="cart-shopping" iconType="sharp-solid">
    **Customer self-service portals**\
    Index product manuals, installation guides, troubleshooting documentation, and FAQs stored on FTP servers to power customer-facing search experiences. Customers can find answers quickly without contacting support, reducing ticket volume and improving satisfaction.

    **Product documentation and downloads**\
    Make product specifications, datasheets, software installers, and firmware updates discoverable through customer portals. Filter by file type (PDF for manuals, ZIP for downloads) and use path patterns to organize content by product line or model number.

    **Media and resource libraries**\
    Surface marketing materials, product images, videos, and tutorials for customers. Use file size filters to handle large media files and ensure customers can discover the right assets for their needs.
  </Tab>

  <Tab title="Business-to-Business" icon="briefcase" iconType="sharp-solid">
    **Partner and supplier portals**\
    Enable partners, distributors, and suppliers to search shared documentation, contracts, pricing sheets, and product specifications stored on secure FTP servers. Use SFTP with public key authentication to ensure secure access to sensitive business information.

    **Collaborative document repositories**\
    Index shared project files, technical specifications, design documents, and deliverables exchanged with clients or partners. Regular expression patterns can organize content by client, project, or contract period.

    **Vendor and procurement documentation**\
    Make vendor agreements, purchase orders, invoices, and compliance certificates searchable for procurement teams and external auditors. File metadata indexing supports retention policies and audit requirements.
  </Tab>

  <Tab title="Knowledge Management" icon="lightbulb" iconType="sharp-solid">
    **Internal knowledge bases**\
    Create a centralized, searchable repository of technical documentation, policies, procedures, and training materials stored across legacy FTP servers. Your employees can find critical information without manually browsing directory structures or knowing exact file locations.

    **Cross-departmental file discovery**\
    Index documents from engineering, sales, legal, and operations departments that still use FTP for file distribution. You can use path patterns like `/departments/(engineering|sales)/.*` to index multiple paths and directories in Fusion, so you don't have to remember whether a file is in the sales FTP server or the marketing FTP server.

    **Compliance and records management**\
    Automatically index file metadata such as modification dates, file sizes, and paths to support regulatory compliance and retention policies. The connector tracks all files in regulated environments where FTP servers store compliance documents, contracts, or audit records.
  </Tab>
</Tabs>

## Prerequisites

Be sure you've satisfied these prerequisites so the FTP Pro connector can reliably access, crawl, and index your data.

### FTP server access requirements

* **FTP or FTPS:** Valid username and password with read permissions to the directories you want to crawl.
* **SFTP:** Username with either password authentication or SSH private key authentication.
* **Network access:** Ensure Fusion can reach the FTP server on the configured port. This port is typically port 21 for FTP and FTPS, or port 22 for SFTP.
* **Firewall rules:** For Fusion cloud deployments, configure egress rules to allow connections to your FTP server.

### Additional requirements for remote connectors

You may run this connector remotely. To run the connector remotely behind a firewall, you need:

* A Fusion user with the `remote-connectors` or `admin` role for gRPC authentication
* The `connector-plugin-standalone.jar` alongside the FTP Pro connector's ZIP file on the remote host
* A configured connector backend gRPC endpoint in your YAML configuration
* A truststore file path if the remote host doesn't trust Fusion's TLS certificate

See [Remote V2 connectors](/docs/fusion-connectors/developers/remote-v2-connectors) for information about configuring remote V2 and Pro connectors.

## Authentication

The FTP Pro connector supports multiple authentication methods depending on your protocol and security requirements. Select the connection type and enter the relevant fields.

### FTP and FTPS authentication

For FTP and FTPS connections, provide the following:

* **Username:** Valid FTP account username
* **Password:** Password for the FTP account

These credentials are used with Apache Commons Net for both standard FTP and explicit SSL/TLS (FTPS) connections.

### SFTP password authentication

For SFTP connections using password authentication, provide the following:

* **Username:** Valid SFTP account username
* **Password:** Password for the SFTP account

### SFTP public key authentication

For enhanced security, SFTP supports SSH public key authentication. Provide the following:

* **Username:** Valid SFTP account username
* **SSH Private Key:** The private key content (PEM format)
* **SSH Private Key Passphrase:** (Optional) Passphrase if the private key is encrypted

This authentication method is recommended for production environments and automated indexing jobs where password rotation policies may disrupt scheduled crawls.

<Frame caption="FTP Pro SSH private key and passphrase">
  <img src="https://mintcdn.com/lucidworks/YBuoMvvXGLxHhc6k/assets/images/connectors/ftp-pro-ssh-key-authentication.png?fit=max&auto=format&n=YBuoMvvXGLxHhc6k&q=85&s=52849c4cf37f853c1bc67dbc5189c2d4" width="1560" height="264" data-path="assets/images/connectors/ftp-pro-ssh-key-authentication.png" />
</Frame>

### Host key verification for SFTP

You may configure host key verification for SFTP connections in order to verify your server's identity and protect against man-in-the-middle attacks. Enter the SHA-256 or MD5 SSH host key fingerprint in the **Trusted SSH Host Key Fingerprint** field. You can obtain the host key fingerprint by connecting to the server with an SSH client and recording the fingerprint displayed during the first connection.

<Frame caption="FTP Pro SSH host key fingerprint">
  <img src="https://mintcdn.com/lucidworks/YBuoMvvXGLxHhc6k/assets/images/connectors/ftp-pro-sftp-trusted-host-fingerprint.png?fit=max&auto=format&n=YBuoMvvXGLxHhc6k&q=85&s=81e9185913ad540ccb7ed78987c4791d" width="1590" height="256" data-path="assets/images/connectors/ftp-pro-sftp-trusted-host-fingerprint.png" />
</Frame>

<Note>
  Host key verification is strongly recommended for production SFTP deployments to ensure you're connecting to your server.
</Note>

## Crawl options

### Maximum directory depth

The **Maximum Depth Level** setting limits how deep the connector descends into subdirectories. For example, with an initial path of `/documents` and a max depth of 2, the connector will crawl the contents of `/documents/folder1/folder2/` but not the contents of `/documents/folder1/folder2/folder3/`.

To crawl only top-level directories, set the field's value to `1`. To perform a full recursive crawl, set the value to `0`.

### Index folder metadata

When the **Index Folder Metadata** field is enabled, the FTP Pro connector indexes each directory as a document containing:

* Directory name
* Full path
* Modification date
* Permissions metadata

This setting is useful for creating a complete file system hierarchy in your search index or for finding directories by name.

### Index failed documents

When a file fails to download or process, enabling the **Index Failed Documents** field creates a document with available metadata but without file content. This helps track which files may need attention.

The indexed metadata includes the following values:

* File name and path
* File size
* Modification date
* Error information

## Intelligent retry mechanism

The FTP Pro connector includes a retry mechanism. This ensures reliable indexing even when facing transient network failures, server timeouts, or temporary unavailability. Additionally, the connector uses exponential backoff between retries, starting with a short delay and increasing with each subsequent retry. This feature prevents overwhelming a struggling server while still providing multiple opportunities to succeed. You can set the number of retry attempts in the **Retry Count** field.

The connector intelligently determines which errors should be retried and which indicate permanent failures.

For FTP or FTPS errors:

* **4xx response codes**: Retry (temporary server issues)
* **5xx response codes**: Don't retry (permanent errors)

For SFTP errors:

* **Network errors**: Retry (temporary connectivity issues)
* **Permission errors**: Don't retry (permanent access denial)

General errors:

* **Timeouts**: Retry (temporary network congestion)
* **DNS failures**:  Don't retry (configuration error)
* **Authentication failures**:  Don't retry (invalid credentials)

During datasource validation, the retry mechanism is automatically disabled to provide fast feedback. This ensures you quickly see any configuration or connection issues without waiting through retry delays.

## Re-crawl indexing

The FTP Pro connector supports full re-crawls to keep your index synchronized with the FTP server.

For new and modified content, the connector:

* Indexes new files added since the last crawl
* Re-indexes files modified since the last crawl based on the modification timestamp
* Updates metadata for existing documents

The connector relies on Fusion's stray deletion support to remove documents that no longer exist on the FTP server. During a re-crawl, the connector takes the following steps for deleted content:

* The connector tracks all crawled documents in CrawlDB
* During a re-crawl, documents not encountered are marked as stray
* Stray documents are automatically deleted from the index

The re-crawl process ensures your search index accurately reflects the current state of your FTP server without manual cleanup.

## Configuration

<Tip>
  When entering configuration values in the UI, use *unescaped* characters, such as `\t` for the tab character. When entering configuration values in the API, use *escaped* characters, such as `\\t` for the tab character.
</Tip>

<SchemaParamFields schema={schema} />
