What happened?
With multiple --rfc2136-host values and --rfc2136-load-balancing-strategy=round-robin, reads and writes can become deterministically skewed across servers.
In practice, reconciles often do:
- AXFR/read
- DNS update/write
If both operations share the same round-robin counter, the read step advances the counter and the subsequent write step consistently lands on the next server. This can make writes appear stuck to one side of the pair.
What did you expect to happen?
Read balancing and write balancing should rotate independently.
If round-robin is enabled:
- AXFR/list path should have its own rotation state
- Send/update path should have its own rotation state
How to reproduce it?
- Configure ExternalDNS with:
- multiple
--rfc2136-host
--rfc2136-load-balancing-strategy=round-robin
- Enable debug logs.
- Watch repeated reconciles.
- Observe a pattern where:
Fetching records from nameserver ... alternates
Sending message to nameserver ... is offset by the shared counter and can repeatedly favor the opposite server
Root cause
The RFC2136 provider uses a single shared counter for both:
- AXFR/list nameserver selection
- Send/update nameserver selection
Because each reconcile typically performs a read before a write, the shared counter creates deterministic coupling between those two paths.
Impact
- Round-robin does not behave independently for reads and writes
- Writes can appear biased to one server
- Troubleshooting is confusing because failover looks partially correct while update distribution is wrong
Proposed fix
Split the counter into independent state:
listCounter for AXFR/list
sendCounter for SendMessage/update
Example fix shape:
type rfc2136Provider struct {
// ...
listCounter int
sendCounter int
mu sync.Mutex
}
func (r *rfc2136Provider) getNextNameserverForList() string {
return r.getNextNameserver(&r.listCounter)
}
func (r *rfc2136Provider) getNextNameserverForSend() string {
return r.getNextNameserver(&r.sendCounter)
}
What happened?
With multiple
--rfc2136-hostvalues and--rfc2136-load-balancing-strategy=round-robin, reads and writes can become deterministically skewed across servers.In practice, reconciles often do:
If both operations share the same round-robin counter, the read step advances the counter and the subsequent write step consistently lands on the next server. This can make writes appear stuck to one side of the pair.
What did you expect to happen?
Read balancing and write balancing should rotate independently.
If round-robin is enabled:
How to reproduce it?
--rfc2136-host--rfc2136-load-balancing-strategy=round-robinFetching records from nameserver ...alternatesSending message to nameserver ...is offset by the shared counter and can repeatedly favor the opposite serverRoot cause
The RFC2136 provider uses a single shared counter for both:
Because each reconcile typically performs a read before a write, the shared counter creates deterministic coupling between those two paths.
Impact
Proposed fix
Split the counter into independent state:
listCounterfor AXFR/listsendCounterfor SendMessage/updateExample fix shape: