Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The NetSuite Pro

The NetSuite Pro Logo The NetSuite Pro Logo

The NetSuite Pro Navigation

  • Home
  • About Us
  • Tutorials
    • NetSuite Scripting
    • Advanced PDF Templates in NetSuite
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask A Question
  • Home
  • About Us
  • Tutorials
    • NetSuite Scripting
    • Advanced PDF Templates in NetSuite
  • Blog
  • Contact Us
Home/ NetSuite Scripting/SFTP Integration (SuiteScript 2.1)

SFTP Integration (SuiteScript 2.1)

🔹 What you’ll learn

  • Connect to an SFTP server from SuiteScript using N/sftp
  • Upload, download, and list files with robust error handling
  • Store credentials & keys safely (via Script Parameters / credentials)
  • Understand host keys, folders, and common pitfalls

🔹 Prerequisites & Setup

  1. Modules enabled: You’ll use N/sftp, N/file, and N/runtime.
  2. Credentials & config: Put these in Script Parameters (deployment) so you never hardcode:
    • custscript_sftp_host (e.g., sftp.partner.com)
    • custscript_sftp_port (usually 22)
    • custscript_sftp_username
    • custscript_sftp_password or key + passphrase
    • custscript_sftp_hostkey (server’s public host key / fingerprint)
    • custscript_sftp_base_dir (e.g., /inbound or /)
  3. SSH Key (if using key auth): Upload the private key file (PEM) to File Cabinet (e.g., /SuiteScripts/keys/id_rsa.pem) and store its file ID in a parameter custscript_sftp_key_file.
  4. Firewall / allow-listing: Ensure your SFTP server allows NetSuite IPs (if required by your vendor).

⚠️ Security tip: Prefer parameters or NetSuite secure credentials. Don’t hardcode secrets in code or logs.


🔹 Connect helper (password OR key auth)

/**
 * @NApiVersion 2.1
 * @NScriptType ScheduledScript
 */
define(['N/sftp', 'N/runtime', 'N/file'], (sftp, runtime, file) => {

  /**
   * Creates and returns an SFTP connection using either password or key-based auth.
   * All values come from deployment parameters to avoid hardcoding.
   */
  function createConnection() {
    const script = runtime.getCurrentScript();

    // ---- Required basics ----
    const host     = script.getParameter({ name: 'custscript_sftp_host' });     // e.g., sftp.partner.com
    const port     = parseInt(script.getParameter({ name: 'custscript_sftp_port' }) || '22', 10);
    const username = script.getParameter({ name: 'custscript_sftp_username' });
    const hostKey  = script.getParameter({ name: 'custscript_sftp_hostkey' });  // server’s host key/fingerprint
    const baseDir  = script.getParameter({ name: 'custscript_sftp_base_dir' }) || '/';

    // ---- Auth options (choose one) ----
    const password = script.getParameter({ name: 'custscript_sftp_password' }); // if password auth
    const keyFileId = script.getParameter({ name: 'custscript_sftp_key_file' }); // if key auth (File Cabinet ID)
    const passphrase = script.getParameter({ name: 'custscript_sftp_passphrase' }); // for encrypted key

    // Build options object for N/sftp
    const options = {
      username,
      url: host,       // server host
      port,            // 22 by default
      hostKey,         // required by many servers for verification
      directory: baseDir // optional default working dir
    };

    // Use password OR private key
    if (password) {
      options.password = password;
    } else if (keyFileId) {
      const keyFile = file.load({ id: keyFileId });   // load PEM private key
      options.privateKey = keyFile.getContents();     // string content of the key
      if (passphrase) options.passphrase = passphrase;
    } else {
      throw new Error('No SFTP auth provided. Set password or key file parameter.');
    }

    // Create and return the SFTP connection
    return sftp.createConnection(options);
  }

  const execute = () => {
    try {
      const conn = createConnection();
      // If we got here, we’re connected. Do work (upload/list/download) below.
      log.debug('SFTP', 'Connection established successfully.');
    } catch (e) {
      log.error('SFTP Connect Error', (e && e.message) || e);
    }
  };

  return { execute };
});

What to notice

  • All sensitive data is read from parameters.
  • Supports password or key auth (with optional passphrase).
  • hostKey helps prevent man-in-the-middle issues—get this from your SFTP provider.

🔹 Upload a file (to remote directory)

/**
 * @NApiVersion 2.1
 * @NScriptType ScheduledScript
 */
define(['N/sftp', 'N/runtime', 'N/file'], (sftp, runtime, file) => {

  function connect() {
    // reuse the createConnection() logic from previous snippet
    const script = runtime.getCurrentScript();
    const conn = sftp.createConnection({
      url: script.getParameter({ name: 'custscript_sftp_host' }),
      port: parseInt(script.getParameter({ name: 'custscript_sftp_port' }) || '22', 10),
      username: script.getParameter({ name: 'custscript_sftp_username' }),
      password: script.getParameter({ name: 'custscript_sftp_password' }), // or privateKey/passphrase
      hostKey:  script.getParameter({ name: 'custscript_sftp_hostkey' }),
      directory: script.getParameter({ name: 'custscript_sftp_base_dir' }) || '/'
    });
    return conn;
  }

  const execute = () => {
    try {
      const conn = connect();

      // 1) Build a local NetSuite file (could also load an existing file)
      const csv = 'id,name\n1001,ACME\n1002,Wayne Enterprises\n';
      const localFile = file.create({
        name: 'customers.csv',
        fileType: file.Type.CSV,
        contents: csv
      });

      // 2) Choose a remote directory/filename
      const remoteDir = '/inbound'; // ensure this exists and you have permissions
      const remoteName = 'customers_' + Date.now() + '.csv';

      // 3) Upload with replaceExisting when appropriate
      conn.upload({
        directory: remoteDir,
        filename: remoteName,
        file: localFile,
        replaceExisting: true
      });

      log.debug('SFTP Upload', `Uploaded ${remoteName} to ${remoteDir}`);
    } catch (e) {
      log.error('SFTP Upload Error', (e && e.message) || e);
    }
  };

  return { execute };
});

Notes

  • Create or file.load() a File Cabinet file.
  • Remote directories must exist and be writable by your SFTP account.

🔹 Download a file (from remote directory)

/**
 * @NApiVersion 2.1
 * @NScriptType ScheduledScript
 */
define(['N/sftp', 'N/runtime', 'N/file'], (sftp, runtime, file) => {
  function connect() {
    const script = runtime.getCurrentScript();
    return sftp.createConnection({
      url: script.getParameter({ name: 'custscript_sftp_host' }),
      port: parseInt(script.getParameter({ name: 'custscript_sftp_port' }) || '22', 10),
      username: script.getParameter({ name: 'custscript_sftp_username' }),
      password: script.getParameter({ name: 'custscript_sftp_password' }),
      hostKey:  script.getParameter({ name: 'custscript_sftp_hostkey' }),
      directory: script.getParameter({ name: 'custscript_sftp_base_dir' }) || '/'
    });
  }

  const execute = () => {
    try {
      const conn = connect();

      // 1) Identify remote file
      const remoteDir = '/outbound';
      const remoteName = 'report_latest.csv';

      // 2) Download returns file contents as a string/bytes
      const contents = conn.download({
        directory: remoteDir,
        filename: remoteName
      });

      // 3) Save to File Cabinet (optional)
      const saved = file.create({
        name: 'downloaded_report.csv',
        fileType: file.Type.CSV,
        contents: contents
      });
      saved.folder = 123; // replace with a real folder ID
      const fileId = saved.save();

      log.debug('SFTP Download', `Saved File Cabinet copy as ID ${fileId}`);
    } catch (e) {
      log.error('SFTP Download Error', (e && e.message) || e);
    }
  };

  return { execute };
});

🔹 List a directory

/**
 * @NApiVersion 2.1
 * @NScriptType ScheduledScript
 */
define(['N/sftp', 'N/runtime'], (sftp, runtime) => {
  const execute = () => {
    try {
      const script = runtime.getCurrentScript();
      const conn = sftp.createConnection({
        url: script.getParameter({ name: 'custscript_sftp_host' }),
        port: parseInt(script.getParameter({ name: 'custscript_sftp_port' }) || '22', 10),
        username: script.getParameter({ name: 'custscript_sftp_username' }),
        password: script.getParameter({ name: 'custscript_sftp_password' }),
        hostKey:  script.getParameter({ name: 'custscript_sftp_hostkey' })
      });

      const path = script.getParameter({ name: 'custscript_sftp_list_dir' }) || '/';
      const items = conn.list({ path }); // returns array of file/dir metadata

      items.forEach((it) => {
        log.debug('SFTP Item', `${it.name} | ${it.directory ? 'DIR' : 'FILE'} | size=${it.size}`);
      });
    } catch (e) {
      log.error('SFTP List Error', (e && e.message) || e);
    }
  };
  return { execute };
});

🔹 Common errors & fixes

Error / SymptomLikely CauseFix
Handshake failed / Permission deniedWrong username/password or key/permissionsVerify creds, reset password or re-upload correct private key; confirm account permissions on SFTP
Host key verification failedhostKey doesn’t match serverAsk your partner for the current host key or fingerprint; update parameter
No such fileWrong remote directory or filenameConfirm path (case-sensitive), ensure directory exists and your user has rights
Upload works but empty file appearsSending empty content or encoding issueConfirm file contents, avoid binary mismatch; for binary, ensure proper handling
Random failures on large filesTimeout / network hiccupsRetry logic, smaller chunks, coordinate with vendor on size/timeouts
Works in Sandbox, fails in ProdDifferent params / firewallCopy parameters to Prod; allow-list NetSuite IPs if vendor requires

🔹 Best practices

  • Never hardcode passwords or keys; use parameters (or NetSuite secure credentials).
  • Use an integration-only SFTP user with least privileges.
  • Log context, not secrets (e.g., don’t log passwords, host keys, file contents).
  • Validate remote paths before calling upload/download.
  • For large batch transfers, stage files to File Cabinet first; then upload.
  • Add retries and governance checks in larger jobs; consider Map/Reduce to generate or process many files.

âś… Key Takeaway

SFTP from SuiteScript is straightforward once you:

  • Store secrets as parameters
  • Provide the correct host key
  • Use N/sftp for connect → upload/list/download
  • Wrap everything in try–catch and log clearly
Share
  • Facebook

Sidebar

Ask A Question

Stats

  • Questions 6
  • Answers 6
  • Best Answers 0
  • Users 2
  • Popular
  • Answers
  • Rocky

    Issue in running a client script in NetSuite SuiteScript 2.0 ...

    • 1 Answer
  • admin

    How can I send an email with an attachment in ...

    • 1 Answer
  • admin

    How do I avoid SSS_USAGE_LIMIT_EXCEEDED in a Map/Reduce script?

    • 1 Answer
  • admin
    admin added an answer The issue is usually caused by following Wrong script file… September 14, 2025 at 10:33 pm
  • admin
    admin added an answer Steps to send an Invoice PDF by email: define(['N/email', 'N/render',… August 28, 2025 at 3:05 am
  • admin
    admin added an answer This error means your script hit NetSuite’s governance usage limit… August 28, 2025 at 3:02 am

Top Members

Rocky

Rocky

  • 1 Question
  • 21 Points
Begginer
admin

admin

  • 5 Questions
  • 2 Points

Trending Tags

clientscript netsuite scripting suitescript

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

© 2025 The NetSuite Pro. All Rights Reserved