Scroll to navigation

TFTPD(8) System Manager's Manual TFTPD(8)

NAME

tftpd - Trivial File Transfer Protocol server

SYNOPSIS

in.tftpd [options...] directory...

DESCRIPTION

tftpd is a server for the Trivial File Transfer Protocol. The TFTP protocol is extensively used to support remote booting of diskless devices. The server can be run as a standalone daemon or it can be started by or

directory... should specify one or more directories to which tftpd may have access. Note that if the --path-prefix option (see below) has been specified, the directory names listed should not include the prefix itself.

The directory names must follow the rules described under PATH VALIDATION, or they will be rejected; notably they must begin with “/” and may not contain “.” or “..” components.

“/” is only allowed as a directory in conjunction with the --path-prefix option.

OPTIONS

Some options are configurable at compile time and may not be available on any one specific system. Run tftpd with the -V option to see which specific options are available on your system.

-4, --ipv4
Connect with IPv4 only, even if IPv6 support was compiled in.
-6, --ipv6
Connect with IPv6 only, if compiled in.
Run the server in standalone (listen) mode, rather than run from a service daemon. In standalone mode, the --address option can be used to specify a specific local address or port to listen to and the --port can be used to specify a default listen port.
Similar to --listen but do not detach from the foreground process. Implies --listen.
-a, --address [address][:port]
Specify a specific address and port to listen to when running in standalone mode (with the --listen or --foreground options.) Numeric IPv6 adresses must be enclosed in square brackets to avoid ambiguity with the optional port information.
If no address is specified, the default is to listen to all local addresses.
port can be either a decimal number between 1 and 65535, or a service name specified in the database. If no port is specified, the default is used; see the --service option.
The --address option may be specified multiple times, and if the address is a host name that resolves to multiple addresses, tftpd will bind to all of them.
Specify the port/service name to use in standalone mode unless a port is explicitly specified in the --address option. Regardless of which name is used for the option, the port can be either a decimal number or a service name specified in the database. The default is "tftp".
Allow new files to be created. By default, tftpd will only allow upload of files that already exist. Files are created with default permissions allowing anyone to read or write them, unless the --permissive or --umask options are specified.
Disable all upload functionality, no matter what the filesystem permissions are set to. All write requests will be denied immediately.
Limit uploads to at most size bytes. A write request that includes an RFC 2349 tsize value greater than size is denied immediately. Uploads without tsize, or whose data exceeds their specified tsize, are terminated with an error. A size of zero is equivalent to --read-only.
-s, --secure, --chroot
Change root directory on startup using This means the remote host does not need to pass along the directory as part of the transfer, and may add security. When --secure is specified, exactly one directory should be specified on the command line.
Note that when --secure is used, none of the path name checks described under PATH VALIDATION below are performed unless --validate is also specified; any desired checks will have to be implemented using explicit remap rules.
Using --secure requires tftpd to be started out as root, and run as root for a considerable amount of time. Consider very carefully if this is genuinely desirable as oppposed to running the daemon as an unprivileged user and using the --map-file, --normalize, and/or --path-prefix options instead, or if supported on your system, the --jail option.
-j, --jail
Resolve file names under a virtual root directory. This is an alternative to --secure which may allow the daemon to not be started as root, but requires that the system call to be supported on the running system; as of September 2026 this is only supported on newer Linux systems. If your system does not support --jail it exits with an error message. When --jail is specified, exactly one directory should be specified on the command line.
Note that when --jail is used, none of the path name checks described under PATH VALIDATION below are performed unless --validate is also specified; any desired checks will have to be implemented using explicit remap rules.
Perform path validation even if --secure or --jail are used. Normally path validation is only performed when neither of those options are specified. See PATH VALIDATION below.
Prepends prefix to the local filesystem path after filename remapping and path validation (see below) have taken place. tftpd verifies that prefix refers to an existing directory, but performs no other validity or permissions checks.
If the --secure or --jail option is used, prefix is instead prepended to the root path; in other words:
--path-prefix /var/lib --secure /tftpboot
is exactly equivalent to:
--secure /var/lib/tftpboot
Specify the username which tftpd will run as; the default is "nobody". The user ID, group ID, and (if possible on the platform) the supplementary group IDs will be set to the ones specified in the system permission database for this username.
Sets the umask for newly created files to the specified value. The default is zero (anyone can read or write) if the --permissive option is not specified, or inherited from the invoking process if --permissive is specified.
See
Perform no additional permissions checks above the normal system-provided access controls for the user specified via the --user option.
-P, --pidfile pidfile
When run in standalone mode, write the process ID of the listening server into pidfile. On normal termination (SIGTERM, SIGINT, or inactivity timeout) the pid file is automatically removed.
How long, in seconds, to wait for a connection before terminating the server. Typically when run from a service daemon, the service daemon will then respawn the server if a new connection arrives.
The default is 0 (unlimited) if run standalone, otherwise 900 (15 minutes.)
Determine the default packet timeout, in microseconds, before a packet is retransmitted. This can be modified by the client if the timeout or utimeout option is negotiated. The default is 1000000 (1 second.)
For subsequent retransmissions of the same packet, tftpd applies exponential backoff as required by RFC 1123.
Specify the use of filename remapping. The remap-file is a file containing the remapping rules, if compiled in. See the section on filename remapping below.
Specify the number of remapping rules that may be executed before the filename mapping fails. The default is 4096.
Read the lines in the file inputfile and process each of them as if they were a file name received from a client. Each valid rewritten filename is then written to standard output, and tftpd terminates.
Implies --stderr --foreground.
Use the --ipv4 and --ipv6 options to simulate an IPv4 or IPv6 client. If --create is included on the command line, simulate a PUT (WRQ) request, otherwise simulate a GET (RRQ) request.
If the --normalize option is used, the output will also be normalized.
Normalize the path name. If remapping is used, normalization is applied after remapping. mode can be none, root, or path.
If mode is none, no normalization is done. This is the default.
If mode is root, then a leading slash is prepended if there is none.
If mode is path, then a leading slash is prepended if there is none, duplicate slashes and “.” pathname components are removed, and “..” pathname components are removed together with the previous pathname component, if one exists. This is the default if mode is not specified. Note that the actual file system contents are not examined; thus, symbolic links or missing directories are not taken into account.
This option can be used with --path-prefix to obtain an effect similar to --secure or --jail without needing a full remap file. See "FILENAME PROCESSING" below.
Increase the logging verbosity of tftpd. This flag can be specified multiple times for even higher verbosity.
Set the verbosity value to value. This is equivalent to specifying the -v option value times.
-r, --refuse, --reject tftp-option
Indicate that a specific RFC 2347 TFTP option should never be accepted, even if requested by the client. This can be used to work around broken clients.
Disable all RFC 2347 options. Requests containing options proceed directly to the normal TFTP data stage without an option acknowledgment.
Specifies the maximum permitted block size. The permitted range for this parameter is from 512 to 65464, or it can be specified as “mtu”, or “mtu-slack”. When mtu is specified, tftpd will try to query the maximum transmission unit (MTU) from the kernel and size the maximum block size accordingly. If slack is specified, the MTU value will be adjusted downward by slack bytes.

Some embedded clients request large block sizes and yet do not handle fragmented packets correctly; for that reason --blocksize mtu is recommended if you might have these kinds of clients on your network.

Specifies the maximum accepted RFC 7440 windowsize option value. The permitted range is from 1 to 32768. A client request exceeding this limit is reduced to this value. If the resulting window is one block, the windowsize option is not returned and the transfer uses normal lockstep operation.
The compile-time default is set by the TFTPD_MAX_WINDOWSIZE configure variable and defaults to 256.
Limits the negotiated window such that the negotiated block size multiplied by the window size does not exceed max-window-bytes. A value of zero, the default, disables this limit. A limit that permits fewer than two blocks causes the server to use normal lockstep operation instead of returning a windowsize option.
The compile-time default is set by the TFTPD_MAX_WINDOWBYTES configure variable) and defaults to 4194304 (4 MiB).
Force the server port number (the Transaction ID) to be in the specified range of port numbers. This can be used to make filewall rules or packet tracing easier.
The min-port and max-port values must be decimal numbers between 1 and 65535.
Log messages to standard error instead of syslog.
Use systemd socket activation. This option is only used in a systemd unit file. See
This also makes the tftpd process run in the foreground, as if the --foreground option had been specified, but unlike the --foreground option it does not change the default for the --timeout option.
Print the version number and configuration to standard output, then exit gracefully. No daemon process is started and no listening sockets are set up.

RFC 2347 OPTION NEGOTIATION

This version of tftpd supports RFC 2347 option negotation. Currently implemented options are:

Set the transfer block size to anything less than or equal to the specified option. This version of tftpd can support any block size up to the theoretical maximum of 65464 bytes.
Set the transfer block size to anything less than or equal to the specified option, but restrict the possible responses to powers of 2. The maximum is 32768 bytes (the largest power of 2 less than or equal to 65464.)
Report the size of the file that is about to be transferred. This version of tftpd only supports the tsize option for binary (octet) mode transfers. For upload (write) transactions, it is acknowledged unchanged and, if --max-upload is specified, used to enforce the upload limit.
Set the time before the server retransmits a packet, in seconds.
Set the time before the server retransmits a packet, in microseconds.
Set the number of data blocks sent before an acknowledgment is required. The maximum value is set by the --windowsize and --window-bytes options. A window can be retransmitted in whole or in part depending on the specific acknowledgement packets received from the client.
Set the block number to resume at after a block number rollover. The default and recommended value is 0, but some clients expect 1 instead.

This version of tftpd only accepts 0 and 1 as valid rollover values.

The cookie option accepts an arbitrary string of up to 255 bytes, and echoes it back to the client as part of the reply (OACK) packet. The cookie string can be used:
1.
By the client, to identify that the reply packet matches the request packet. Standard TFTP makes this difficult, because the TFTP server normally returns the initial response using a different port number, and under some circumstances even a different IP address.
2.
By the server, to detect duplicate reception (due to retransmission) of request packets, as opposed to a new transmission session.

The --refuse option can be used to disable specific options; this may be necessary to work around bugs in specific TFTP client implementations. For example, some TFTP clients have been found to request the blksize option, but crash with an error if they actually get the option accepted by the server.

The --refuse-all option disables all TFTP options, and thus the server will never return an OACK packet.

FILENAME PROCESSING

The filename requested by the server goes through the following steps, in this order:

1.
If the --map-file option is used, filename remapping. See "FILENAME REMAPPING" below.
2.
If the --normalize option is used, filename normalization. See the --normalize option above.
3.
If the --secure or --jail options are not used, or the --validate option is specified, path validation. See "PATH VALIDATION" below.
4.
If the --path-prefix option is used, the path prefix is prepended.

FILENAME REMAPPING

The --map-file option specifies a file which contains filename remapping rules. Each non-comment line (comments begin with hash marks, #) contains either a label, preceeded by a colon:

:label

or an operation, specified below, followed by an extended regular expression regex (see and optionally a replacement pattern. The operation indicated by operation is performed if the regex matches all or part of the filename. Rules are processed from the top down, and by default, all rules are processed even if there is a match.

Sometimes it is useful to have a rule that always matches, in that case, the regular expression:

^

(a single caret symbol) can be used.

The operation can be any valid combination of the following characters:

Replace the substring matched by regex by the replacement pattern. The replacement pattern may contain escape sequences; see below.
r cannot be used with ~, a, or j.
Repeat the replacement until it no longer matches, searching the whole string, including replacements, from the beginning each time.
g is always used with r.
Repeat the replacement until it no longer matches, but only on the portion of the string that has not yet been matched, similar to how the s command with the g option works in
gg is always used with r.
Match the regex case-insensitively. By default it is case sensitive.
If this rule matches, end rule processing after executing the rule.
e cannot be used with a, E, j, or s.
If this rule matches, and the result matches a filename that can be transferred, end rule processing after executing the rule. If this is used with r, then if the substitution does not result in a valid filename, the substitution is undone.
E cannot be used with a, e, j, or s.
If this rule matches, start rule processing over from the very first rule after executing this rule.
s cannot be used with a, e, E, or j.
If this rule matches, refuse the request and send an access denied error to the client.
a cannot be used with e, E, j, r, or s.
If this rule matches, jump to the label specified by replacement pattern.
This rule applies to GET (RRQ) requests only.
This rule applies to PUT (WRQ) requests only.
4
This rule applies to IPv4 sessions only.
6
This rule applies to IPv6 sessions only.
~
Inverse the sense of this rule, i.e. execute the operation only if the regex doesn't match.
~ cannot be used with r.

The following escape sequences are recognized as part of a replacement pattern:

\0
The entire string matched by the regex.
\1 to \9
The strings matched by each of the first nine parenthesized subexpressions, (...), of the regex pattern.
\i
The IP address of the requesting host, in dotted-quad notation for IPv4 (e.g. 192.0.2.169) or conventional colon form for IPv6 (e.g. 2001:db8::1).
\x
The IP address of the requesting host, in expanded hexadecimal notation (e.g. C00002A9 for IPv4, or 20010DB8000000000000000000000001 for IPv6).
\\
Literal backslash.
\whitespace
Literal whitespace.
\#
Literal hash mark.
\U
Turns all subsequent letters to upper case.
\L
Turns all subsequent letters to lower case.
\E
Cancels the effect of \U or \L.

If the mapping file is changed, you need to send SIGHUP to any outstanding tftpd process.

PATH VALIDATION

If the --secure or --jail options are not given on the command line, or the --validate option is given, tftpd will perform the following validation and canonicalization of the final path name, before verifying that the path falls inside one of the directories specified on the command line (similarly canonicalized):

1.
The path name must begin with “/”.
2.
The path must not contain “.” or “..” components.
3.
The path name must not contain ASCII control characters (0-31).
4.
Consecutive and terminal slashes are removed.
5.
On Windows platforms, the characters < > : " \ | ? * that are invalid in filenames are prohibited. Only forward slashes (“/”) are permitted as a path separator. A path name component cannot end in a “.” or space character, and each path name component is checked against the list of hard-coded Windows reserved filenames.

Validation and canonicalization are performed after filename remapping, if remapping is used.

If the --path-prefix option is specified, then the path prefix is prepended after path validation has taken place.

When --secure or --jail is used, no path validation is performed by tftpd itself.

SECURITY

The use of TFTP services does not require an account or password on the server system. Due to the lack of authentication information, tftpd will allow only publicly readable files (o+r) to be accessed, unless the --permissive option is specified. Files may be written only if they already exist and are publicly writable, unless the --create option is specified. Note that this extends the concept of ``public'' to include all users on all hosts that can be reached through the network; this may not be appropriate on all systems, and its implications should be considered before enabling TFTP service.

If there is no need for the server to accept write (upload) requests, it is a good idea to specify the --read-only command line option to prevent any accidental setting of filesystem permissions to inadvertently allow uploads.

It is strongly recommended to use some kind of firewall or packet-filter solution to restrict access to the TFTP port. TFTP only uses the TFTP port itself for the initial (request) packet, and so the cost of such a filter is neglible.

The server should be set to run as the user with the lowest possible privilege; please see the --user flag. It is strongly recommended to set up a specific user account for tftpd, rather than letting it run as "nobody", to guard against privilege leaks between applications.

Access to files is restricted by the list of directories passed to tftpd on the command line. Alternatively, the --secure or --jail flag can be used to set up a virtual root environment for the server to run in once a connection has been set up.

The filename mapping facility (--map-file flag) support can be used to provide fine-grained control of permissions as well handle nonstandard path names requested by clients, such as Windows clients expecting to be able to use \ as path separators.

Make sure to examine the "FILENAME PROCESSING" flow to ensure than the path names actually processed are the ones intended.

CONFORMING TO

RFC 1123, Requirements for Internet Hosts - Application and Support.
RFC 1350, The TFTP Protocol (revision 2).
RFC 2347, TFTP Option Extension.
RFC 2348, TFTP Blocksize Option.
RFC 2349, TFTP Timeout Interval and Transfer Size Options.
RFC 7440, TFTP Windowsize Option

AUTHOR

This version of tftpd is maintained by H. Peter Anvin <hpa@zytor.com>. It was derived from, but has substantially diverged from, an OpenBSD source base, with added patches by Markus Gutschke and Gero Kulhman.

BUGS

TFTP is an incredibly inefficient protocol, even with the windowsize option enabled. These inefficiencies are inherent in the protocol and can be partially worked around, but never fixed. Its only justification is that an embedded TFTP client can be implemented in an extremely small ROM.

Embedded TCP stacks are now readily available, and generally occupy less storage than the hardware driver layer. Vendors of embedded network hardware should strongly consider using a simple TCP-based protocol such as HTTP/1.0 instead.

“Those who do not understand TCP are condemned to reimplement it, poorly, at the wrong level.”

SEE ALSO

20 September 2026 tftp-hpa 7.2