ZTP Loop and Duplicate Identity After Leaf Replacement
A 64-switch EVPN fabric is deployed with ZTP. DHCP option 66 points to 10.0.0.10 and option 67 to /ztp/junos-qfx-x86-64-22.4R3-S1.8.tgz. Each switch's serial number maps to a hostname and a config file at /ztp/configs/.conf. Eight switches installed last week repeatedly reboot into ZTP, even though they receive a management IP and the TFTP server logs successful image transfers. A replacement switch, serial JN1234567, is installed for a failed leaf-17 but comes up with hostname leaf-19 and the leaf-19 config, including a duplicate loopback 10.0.0.19/32 and duplicate BGP router ID. A manually corrected config on one leaf reverted after a power cycle. No Apstra or other automation controller is in use.
1. What are the likely causes of the ZTP loop and the duplicate identity, and what would you check first?
Read the worked answer
The ZTP loop usually means the device is not reaching a terminal state: the image download may succeed but the checksum or install fails, or the config file is missing, unreadable, or rejected. Check show system autoinstallation status on one looping switch, the TFTP server's requested filename, file permissions, and the image checksum. If option 67 names S1.8 but the server has a different build or a truncated file, the transfer can log as successful and still fail verification. The duplicate identity is a separate mapping error: the replacement received the leaf-19 config because the serial-to-config mapping is wrong, the DHCP server hands out a fixed option 67 by MAC or port, or the config file is a copy of leaf-19 rather than a serial-specific bootstrap. Check show dhcp client binding, the DHCP server's option 67, and the file content. A duplicate loopback and router ID in an EVPN fabric will cause BGP and Type-2 and Type-5 instability, so isolate the replacement before it peers.
2. Why did a manually corrected config revert after a power cycle, and how should ZTP be scoped for day-2 operations?
Read the worked answer
A manual config should survive a power cycle if it was committed and saved on the active root. If it reverted, check whether it was only a candidate config, whether commit confirmed was used and not confirmed, or whether the device booted from the backup root slice after a failed primary boot. show system storage partitions and show system boot-messages will show which slice is active. The other possibility is that ZTP is still enabled and is re-applying a full config at boot. ZTP should provision only the bootstrap: hostname, management address, user credentials, NETCONF, and then disable autoinstallation. Day-2 configuration should be owned by Apstra or an Ansible/PyEZ pipeline, not by a ZTP file. After bootstrap, run request system autoinstallation disable, take a snapshot, and verify that a reboot does not re-enter ZTP. Keep the ZTP config minimal and idempotent.
3. What would you change in the deployment process to prevent duplicate IPs and make a replacement deterministic?
Read the worked answer
Use a single source of truth for serial, hostname, loopback, ASN, and management IP, and validate it before deployment. Generate the bootstrap per serial; do not copy a full config from another leaf. Add a pre-check that rejects duplicate loopbacks and router IDs, and a post-ZTP check that verifies the hostname, loopback uniqueness, BGP router ID, and EVPN session state. If DHCP cannot select a config by serial, use option 82 or a per-port DHCP policy, or pre-stage the file and let the switch request it by serial. For scale and day-2, move to Apstra with device profiles and property sets, or an Ansible inventory, so the intended config is rendered from the source of truth. Remove stale TFTP files, set permissions and checksums, and keep an image version map. Test the replacement workflow in a lab with a spare switch and a duplicate serial scenario, then document the rollback.