skip to content

What does the NTP Reference ID field carry at each stratum, and how does it help a server avoid a timing loop?

level: middleimportance: should knowfreq 14%

answer

  1. one 32-bit field, three meanings
  2. kiss code, clock code, upstream address
  3. IPv6 gets a hash
  4. seeing your own address upstream
  5. only one hop deep

basics

~20 s

The 32-bit Reference ID holds a kiss code at stratum 0, a reference clock code such as GPS at stratum 1, and the upstream server's identity above that. A server seeing its own address there knows that source follows it.

solid answer

~40 s

In NTPv4 (RFC 5905) the `Reference ID` is a 32-bit field whose meaning depends on `Stratum`: at 0 it is a four-character kiss code such as `DENY` or `RATE`; at 1 it is the reference clock's left-justified ASCII code, such as `GPS` or `PPS`; above 1 it identifies the server this host is synchronised to - its IPv4 address, or the first four octets of the MD5 hash of its IPv6 address. That lets a server detect a timing loop: if a candidate source's Reference ID equals the server's own address, that source is synchronised to it, and following it would make the two clocks chase each other, so the server rejects it. The check sees only one hop, so a longer ring is not caught by it.

go deeper

for a junior

Recall that the Reference ID names where a server gets its time: a clock code like GPS at stratum 1 and the upstream server's address above it.

for a middle

Explain the three meanings by stratum, the IPv6 MD5-hash rule, and the exact test: a candidate whose Reference ID equals my own address is following me, so it is unfit.

for a senior

Show where the check fails - multi-hop rings, IPv6 hash collisions, NTPv3 clients - and design same-tier backup so servers cannot settle into following each other when upstreams vanish.

for a principal

Weigh the refid's operational value against what it discloses about your topology, and judge whether draft NTPv5's random IDs and Bloom filter justify planning for it.

## One field, three meanings Every NTP header carries a 32-bit `Reference ID` (`refid` in RFC 5905's variable names). What it holds depends on the `Stratum` field of the same packet: | Stratum | Reference ID content | Example | |---|---|---| | 0 (unspecified or invalid) | a four-character ASCII **kiss code** | `DENY`, `RSTR`, `RATE` | | 1 (primary server) | a left-justified, zero-padded ASCII code naming the **reference clock** | `GPS`, `PPS`, `DCF` | | 2-15 (secondary) | the identity of the **server this host is synchronised to** | IPv4: that server's four-octet address | Some details matter: - The stratum 1 codes are kept in an **IANA registry**; codes beginning with `X` are reserved for unregistered experimentation. - For IPv6, a 128-bit address does not fit in 32 bits, so RFC 5905 uses the **first four octets of the MD5 hash** of the upstream server's IPv6 address. - Kiss codes are what a server uses to tell a client to back off or stop; their handling belongs with securing time sources. ## What a timing loop is NTP is meant to form a tree rooted at primary servers. A **timing loop** happens when two or more servers end up synchronising to each other: A follows B while B follows A. Each corrects towards the other, so the pair can wander together away from UTC while agreeing perfectly - positive feedback with no reference in it. Loops are a real risk wherever same-tier servers back each other up. In a data centre whose four internal servers normally follow two GPS-fed appliances, losing both appliances leaves the internal servers with only each other to follow. ## How the Reference ID breaks the loop RFC 5905 says that above stratum 1 the Reference ID "can be used to detect timing loops". The test its reference skeleton applies when judging whether a source is fit is direct: 1. Server B receives a packet from candidate source A. 2. A's Reference ID names the server A is synchronised to. 3. If that value equals **B's own address**, A is following B. 4. B treats A as unfit - using it would close a loop - and looks elsewhere. Stratum adds a second, slower brake: each hop adds one, and RFC 5905's skeleton calls 16 the "infinity metric". In a ring that escapes the check, each server's stratum climbs with every round of updates, and 16 marks the result as unsynchronized - the same count-to-infinity guard distance-vector routing uses. The RFC also floors each hop's dispersion increment at a minimum value, which it says avoids loops between peers at the same stratum. ## Where the check falls short - **It sees one hop.** A ring A -> B -> C -> A is invisible to it: A sees C's Reference ID, which names B, not A. - **IPv6 uses a 32-bit hash prefix.** Two addresses can collide, and RFC 5905 warns that an NTPv3 client talking to an IPv6 NTPv4 server sees an apparently random value, so a loop might not be detected. - **It discloses the upstream.** Every reply tells the world which server this host follows. The NTPv5 work addresses these: draft-ietf-ntp-ntpv5-09, an Internet-Draft rather than an RFC, gives each server a random 120-bit reference ID and exchanges the set of IDs in the synchronisation chain as a 4096-bit Bloom filter, so a server can spot its own ID several hops upstream. ## Reading Reference IDs in operation - On a GPS-fed appliance at stratum 1 the field should read `GPS`; on a healthy internal server at stratum 2 it should name one of the appliances. - An internal server whose Reference ID names another internal server has lost its appliances and is following a peer - worth an alert even while its time still looks fine. - Two servers that each name the other should not persist: the one-hop check refuses that path. If it does persist, the check is not working between them, and an NTPv3 host facing an IPv6 NTPv4 server is the case RFC 5905 itself names. - A stratum 0 packet whose field reads `RATE` or `DENY` is not a time source at all but a kiss-o'-death reply. ## Interview takeaway Name the three meanings by stratum, explain the "my own address came back" test, and say plainly that it catches direct loops only - multi-hop rings rely on stratum counting up and on careful topology.

  • Why can the NTPv4 Reference ID miss a loop of three servers?
    Above stratum 1 the field names only the server a host follows directly. In a ring A -> B -> C -> A, A reads C's Reference ID, which names B, so A never sees its own address and the one-hop test passes. Stratum climbing towards 16 and a topology without such rings are the remaining protection.
  • What does draft NTPv5 change about loop detection?
    draft-ietf-ntp-ntpv5-09, still an Internet-Draft, gives each server a random 120-bit reference ID and has servers pass the set of IDs in their synchronisation chain as a 4096-bit Bloom filter. A server finding its own ID in a source's filter assumes a loop and stops using that source, even when the loop spans several hops.

Two colleagues who set their watches only by each other will agree forever and drift together. The Reference ID is a note on each watch saying whose watch it was set from: if you read your own name on the other person's note, stop using their watch.

saying these in an interview costs you the question

  • A secondary server puts its own IP address in the Reference ID
  • The Reference ID always holds a reference clock name like GPS
  • The refid check detects loops of any length
  • IPv6 servers carry their full address in the Reference ID
  • Timing loops cannot form between servers at the same stratum