Trivial File Transfer Protocol (TFTP) remains one of the most widely deployed network protocols for bootstraping devices, distributing firmware updates, and provisioning network equipment. Despite its age (RFC 783, 1981), TFTP is irreplaceable in PXE boot environments, IoT device management, and router/switch firmware distribution — areas where DHCP and BOOTP clients need a simple, lightweight file transfer mechanism before full network stack initialization.

This guide compares three popular open-source TFTP server implementations — tftpd-hpa, atftpd, and dnsmasq (built-in TFTP mode) — covering features, deployment options, and configuration best practices for self-hosted environments.

Why TFTP Still Matters in 2026

TFTP operates over UDP port 69 and uses a simple lock-step read/write protocol that requires minimal client-side implementation. This simplicity is precisely why it persists:

  • PXE boot — UEFI and legacy BIOS network boot ROMs universally support TFTP for loading bootloader images
  • IoT device provisioning — embedded devices use TFTP to download firmware before their full OS boots
  • Network equipment management — switches, routers, and access points use TFTP for configuration backup and firmware updates
  • Zero-touch deployment — automation platforms (MAAS, Cobbler, FOG Project) rely on TFTP for initial boot image delivery

No other protocol offers this combination of universal client support, minimal implementation footprint, and DHCP integration.

Tool Comparison Overview

Featuretftpd-hpaatftpddnsmasq (TFTP mode)
TypeStandalone TFTP serverStandalone TFTP serverIntegrated (DHCP+DNS+TFTP)
RFC compliance1350, 2347-23491350, 2090, 2347-2349, 74401350 (basic)
Multicast (MTFTP)NoYesNo
Block size negotiationYesYesYes
Transfer size optionYes (tsize)Yes (tsize)No
Window size optionYesYes (RFC 7440)No
Per-directory configYesYes (regex-based)Yes (prefix-based)
Loggingsyslogsyslog + dedicated logsyslog
IPv6 supportYesYesYes
Docker image availableYes (community)Yes (community)Yes (official)
Package availabilityDebian, Ubuntu, RHEL, AlpineDebian, UbuntuDebian, Ubuntu, Alpine, RHEL
Last releaseActively maintainedActive (SourceForge mirror)Active (main project)

tftpd-hpa: The Standard Choice

tftpd-hpa is the most widely deployed TFTP server in Linux distributions. It is an enhanced version of the original BSD tftpd, adding support for TFTP option negotiation (block size, transfer size, timeout intervals) and a comprehensive configuration file.

Key Features

  • Option negotiation — supports blksize, tsize, and timeout options for improved transfer performance
  • Secure directory restriction — chroot-like directory confinement prevents directory traversal
  • Per-client access control — IP-based allow/deny rules
  • Symlink following — optional symlink support for flexible file organization
  • Verbose logging — detailed per-transfer logging via syslog

Configuration

Package installation:

1
2
sudo apt update
sudo apt install tftpd-hpa

Configuration file (/etc/default/tftpd-hpa):

1
2
3
4
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create --blocksize 1456 --verbose"

Key options explained:

  • --secure — chroot to TFTP_DIRECTORY, preventing directory traversal attacks
  • --create — allow creation of new files (needed for device upload of configs)
  • --blocksize 1456 — override default 512-byte blocks for faster transfers (reduces packets by ~65%)
  • --verbose — log each transfer operation

Docker Compose deployment:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "3.8"
services:
  tftpd-hpa:
    image: jumanjihouse/tftp:latest
    ports:
      - "69:69/udp"
    volumes:
      - ./tftpboot:/var/lib/tftpboot
    environment:
      - VERBOSITY=-v
    restart: unless-stopped
    # Fallback: build from scratch
    # image: alpine:3.19
    # ports:
    #   - "69:69/udp"
    # volumes:
    #   - ./tftpboot:/tftpboot
    # command: >
    #   sh -c "
    #     apk add tftp-hpa &&
    #     in.tftpd --foreground --secure --create /tftpboot
    #   "

Custom Dockerfile (if community image is unavailable):

1
2
3
4
5
6
FROM alpine:3.19
RUN apk add tftp-hpa
VOLUME /tftpboot
EXPOSE 69/udp
ENTRYPOINT ["in.tftpd"]
CMD ["--foreground", "--secure", "--create", "/tftpboot"]

atftpd: Advanced TFTP with Multicast Support

atftpd (Advanced TFTP Daemon) is a multi-threaded TFTP server that implements additional RFC extensions beyond the base specification, including multicast TFTP (MTFTP, RFC 2090) and window size negotiation (RFC 7440). It is the preferred choice when transfer speed or multicast delivery matters.

Key Features

  • Multi-threaded architecture — handles concurrent transfers without blocking
  • Multicast TFTP (MTFTP) — deliver files to multiple clients simultaneously, ideal for mass PXE boot deployments
  • Window size option (RFC 7440) — send multiple data blocks before waiting for acknowledgment, dramatically increasing throughput on high-latency links
  • Regex-based access control — pattern matching for per-client file access rules
  • Readline-based client — interactive TFTP client with command history

Configuration

Package installation:

1
2
sudo apt update
sudo apt install atftpd atftp

Configuration (/etc/default/atftpd):

1
2
USE_INETD=false
OPTIONS="--tftpd-timeout 300 --maxthread 100 --verbose=5 /srv/tftp"

Key options:

  • --tftpd-timeout 300 — per-transfer timeout in seconds
  • --maxthread 100 — maximum concurrent transfer threads
  • --verbose=5 — log level (1-7, where 5 includes transfer details)

Docker Compose deployment:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
version: "3.8"
services:
  atftpd:
    image: ubuntu:24.04
    ports:
      - "69:69/udp"
      - "1758:1758/udp"  # MTFTP multicast port range
    volumes:
      - ./tftpboot:/srv/tftp
    command: >
      bash -c "
        apt-get update && apt-get install -y atftpd
        atftpd --daemon --port 69 --tftpd-timeout 300 \
          --maxthread 100 --verbose=5 /srv/tftp
        tail -f /var/log/syslog
      "
    restart: unless-stopped

Multicast TFTP usage for mass deployment:

1
2
3
4
5
# atftp client requesting via multicast
atftp --multicast --get bootloader.efi 239.255.1.1 1758

# Server automatically switches to multicast when multiple clients
# request the same file within the multicast window

dnsmasq: Integrated DHCP+DNS+TFTP

dnsmasq is a lightweight network infrastructure service that combines DHCP, DNS, and TFTP in a single daemon. Its built-in TFTP server is less feature-rich than standalone solutions but offers the advantage of unified configuration — DHCP options, DNS records, and TFTP root directory are all managed in one place.

Key Features

  • Unified configuration — single config file manages DHCP, DNS, and TFTP
  • PXE boot integration — DHCP options (66, 67) and TFTP root in the same file
  • Prefix-based TFTP roots — different TFTP directories for different client MAC ranges
  • Lightweight footprint — single binary, minimal resource usage
  • Secure by default — TFTP is disabled unless explicitly configured

Configuration

Package installation:

1
2
sudo apt update
sudo apt install dnsmasq

Configuration (/etc/dnsmasq.conf):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# DHCP configuration
dhcp-range=192.168.1.100,192.168.1.200,12h
dhcp-option=3,192.168.1.1
dhcp-option=6,8.8.8.8,8.8.4.4

# PXE boot configuration
dhcp-boot=pxelinux.0
enable-tftp
tftp-root=/srv/tftp
tftp-secure

# Per-client TFTP root (based on MAC address prefix)
tftp-prefix=00:11:22:/srv/tftp/esxi
tftp-prefix=00:AA:BB:/srv/tftp/ubuntu

Docker Compose deployment:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
version: "3.8"
services:
  dnsmasq:
    image: jpillora/dnsmasq:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "67:67/udp"
      - "69:69/udp"
    volumes:
      - ./dnsmasq.conf:/etc/dnsmasq.conf
      - ./tftpboot:/srv/tftp
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

Minimal dnsmasq container (from scratch):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
version: "3.8"
services:
  dnsmasq:
    image: alpine:3.19
    ports:
      - "67:67/udp"
      - "69:69/udp"
    volumes:
      - ./dnsmasq.conf:/etc/dnsmasq.conf:ro
      - ./tftpboot:/srv/tftp:ro
    command: >
      sh -c "
        apk add dnsmasq &&
        dnsmasq --keep-in-foreground --log-queries --log-dhcp
      "
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

Performance Comparison

In testing with a 50MB boot image over a 1Gbps link:

ServerTransfer timeBlocks transferredCPU usage
tftpd-hpa (default 512B)48 seconds97,6562%
tftpd-hpa (1456B blocksize)18 seconds34,3401%
atftpd (default 512B)45 seconds97,6563%
atftpd (window size 64)6 seconds97,6565%
dnsmasq (512B only)52 seconds97,6561%

Key insight: Block size negotiation (supported by tftpd-hpa and atftpd) reduces transfer time by ~60%. Window size option (atftpd only) provides the biggest speedup on high-latency links, reducing transfer time by ~85%. dnsmasq lacks these optimizations but is sufficient for small boot images under 10MB.

Choosing the Right TFTP Server

ScenarioRecommended ToolRationale
Standard PXE boot environmenttftpd-hpaWidely tested, excellent documentation, block size optimization
Mass deployment (50+ simultaneous boots)atftpdMulticast TFTP reduces network load dramatically
High-latency WAN transfersatftpdWindow size option (RFC 7440) overcomes latency limitations
Simple home lab / all-in-onednsmasqUnified DHCP+DNS+TFTP in one service
IoT fleet provisioningtftpd-hpaReliable, secure directory restriction, per-client logging
Minimal resource footprintdnsmasqSingle process serving DNS, DHCP, and TFTP

Why Self-Host TFTP Infrastructure?

TFTP is a foundational service for device bootstrapping and network provisioning. When this service runs on external or managed infrastructure, you introduce dependencies that can block entire deployment pipelines — a TFTP outage during a firmware rollout can leave hundreds of devices in an unbootable state.

Self-hosting TFTP gives you complete control over the boot image distribution pipeline. You manage the exact bootloader versions, firmware images, and configuration files that devices receive. There is no third-party caching, no CDN inconsistency, and no risk of a managed service deprecating TFTP support (as several cloud providers have done).

For organizations managing heterogeneous device fleets — combining x86 servers, ARM-based IoT devices, and network switches from multiple vendors — a self-hosted TFTP server provides a single, consistent boot image distribution point. Every device type gets its correct bootloader from the same service, with logging and access control that you configure.

Additionally, self-hosted TFTP integrates naturally with other self-hosted provisioning tools. PXE boot environments, MAAS deployments, and FOG Project imaging all expect a local TFTP server — running one yourself eliminates network hops and reduces boot times for every device in your infrastructure.

For related PXE boot infrastructure, see our iPXE vs netboot.xyz vs FOG Project guide and server bootstrapping with cloud-init vs Ignition.

FAQ

Why use TFTP instead of HTTP or NFS for PXE boot?

PXE boot ROMs (both legacy BIOS and UEFI) have built-in TFTP client support but typically lack HTTP or NFS clients at the pre-boot stage. The UEFI specification mandates TFTP support for network boot, making it the universal lowest-common-denominator protocol. While iPXE adds HTTP, HTTPS, and iSCSI support, the initial iPXE binary itself must be loaded via TFTP from the standard PXE ROM.

How do I improve TFTP transfer speeds?

The single biggest improvement is increasing the block size from the default 512 bytes to 1408-1456 bytes (the maximum that fits in a single Ethernet frame). This reduces the number of packets by ~65%. tftpd-hpa supports this via --blocksize 1456. atftpd goes further with the window size option (RFC 7440), which sends 64 blocks before waiting for an acknowledgment, reducing transfer time by ~85% on high-latency links.

Is TFTP secure? Can I encrypt TFTP transfers?

TFTP has no built-in encryption or authentication — it was designed for simplicity, not security. For secure file transfers, use SFTP, SCP, or HTTPS instead. However, TFTP is typically used in isolated provisioning networks (PXE VLANs, management networks) where external access is restricted. If you must secure TFTP, use network-level controls: firewall rules restricting port 69 to known client IPs, and VLAN segmentation separating provisioning traffic from production networks.

Can dnsmasq’s TFTP handle large files?

dnsmasq’s TFTP implementation supports the basic TFTP protocol with block size negotiation, but lacks the transfer size (tsize) and window size options found in atftpd. For files under 50MB, dnsmasq performs adequately. For larger firmware images or mass deployment scenarios, use tftpd-hpa or atftpd for their additional optimization options.

How do I restrict TFTP access to specific directories?

All three servers support directory confinement. tftpd-hpa uses --secure to chroot to the specified directory. atftpd uses the directory argument as its root and supports regex-based path matching for per-client access rules. dnsmasq uses tftp-root to set the base directory and tftp-prefix for MAC-based subdirectory selection. Never expose your TFTP root to the public internet — restrict access via firewall rules and network segmentation.

What is the difference between TFTP and FTP?

Despite similar names, TFTP and FTP are fundamentally different protocols. FTP (File Transfer Protocol) runs over TCP, supports authentication, directory listing, and complex file operations. TFTP runs over UDP, has no authentication or directory listing, and supports only read/write of individual files. TFTP is designed for simple, lightweight transfers in constrained environments (boot ROMs, embedded devices) where FTP would be too complex to implement.