I apologise, Sebastien, it appears I was not waiting long enough for the router to connect to a directory, then use the headers to find its IP. I had always assumed that the first series of failures to find an IP (before any directories were contacted) was permanent.
This is the debug log output from a secondary test router that I configured on the same IP:
Aug 18 17:47:20.558 [info] {CONFIG} int resolve_my_address(int, const or_options_t *, uint32_t *, const char **, char **)(): Guessed local hostname 'REDACTED.local' resolves to a private IP address (192.168.REDACTED.REDACTED). Trying something else.
Aug 18 17:47:20.558 [info] {CONFIG} int resolve_my_address(int, const or_options_t *, uint32_t *, const char **, char **)(): Interface IP address '192.168.REDACTED.REDACTED' is a private address too. Ignoring.
Aug 18 17:47:20.558 [info] {CONFIG} int resolve_my_address(int, const or_options_t *, uint32_t *, const char **, char **)(): Address 'REDACTED.local' resolves to private IP address '192.168.REDACTED.REDACTED'. Tor servers that use the default DirAuthorities must have public IP addresses.
Aug 18 17:47:20.558 [info] {CONFIG} int router_pick_published_address(const or_options_t *, uint32_t *)(): Could not determine our address locally. Checking if directory headers provide any hints.
Aug 18 17:47:20.558 [info] {CONFIG} int router_pick_published_address(const or_options_t *, uint32_t *)(): Success: chose address '121.REDACTED.REDACTED.REDACTED'.
Once the test router appears in the consensus, I'll make similar changes to the primary router (and it will pick them up on the next restart!)