`location update` failing to exit with 3 when database was already the latest version

Since I would like to skip an export if “the database was already the latest version,” I wanted to be able to use the non-zero exit code to do so…

Either the documentation is incorrect or there’s something wrong with location or I’m failing to understand what “[location update] will terminate with a return code of … 3 if the database was already the latest version” means:

$ man location|grep 'update the local database' -A3 -B1
     update
         This command will try to update the local database.

         It will terminate with a return code of zero if the database has been 
successfully updated. 1 on error, 2  on invalid call and 3 if the database was 
already the latest version.

$ printf \\n;
sudo lla /var/lib/location/database.db; 
sudo location --debug verify; 
sudo location --debug update; 
printf '\nec=%s\n\n' "$?"; 
sudo location --debug update; 
printf '\nec=%s\n' "$?"; 
location --version; 
uname -s -o -v -r

.r--r--r-- 49,532,297 root root  3 Sep 12:27 /var/lib/location/database.db
Database successfully verified
Already on the latest version

ec=0

Already on the latest version

ec=0
location 0.9.19
Linux 6.12.96-1-MANJARO #1 SMP PREEMPT_DYNAMIC Sat, 18 Jul 2026 20:22:19 +0000 GNU/Linux

$ printf \\n;
sudo ls -la /var/lib/location/database.db; 
sudo location --debug verify; 
sudo location --debug update; 
printf '\nec=%s\n\n' "$?"; 
sudo location --debug update; 
printf '\nec=%s\n' "$?"; 
location --version; 
uname -s -o -v -r

-r--r--r-- 1 root root 49532297 Sep  3 10:26 /var/lib/location/database.db
Database successfully verified
Already on the latest version

ec=0

Already on the latest version

ec=0
location 0.9.19
Linux 6.17.0-1020-oracle #20-Ubuntu SMP Sat Jul 25 00:58:05 UTC 2026 GNU/Linux

Thanks!

Hallo @iconoclasthero

Welcome to the IPFire community.

The man page wording needs to be modified.

Return code of 3 is shown if “the database has been updated recently”,
where recently means 1 day if updates are being run via cron/fcron daily or 7 days if weekly or 30 days if monthly.

Return code of 3 is also shown if a new file was not received when trying to download a new database.

https://git.ipfire.org/?p=location/libloc.git;a=blob;f=src/scripts/location.in;h=a93a8d35dcfabb6de4877c11cb1609ca71a0bb20;hb=5ddfdb0abdb68ea85a8c55de9303963843d0be87#l458

https://git.ipfire.org/?p=location/libloc.git;a=blob;f=src/scripts/location.in;h=a93a8d35dcfabb6de4877c11cb1609ca71a0bb20;hb=5ddfdb0abdb68ea85a8c55de9303963843d0be87#l488

EDIT:
Looking further. If it is already at the latest version then the code just has a return and it could be that it needs to be changed to return 3.
I think that would then match with the man page.
https://git.ipfire.org/?p=location/libloc.git;a=blob;f=src/scripts/location.in;h=a93a8d35dcfabb6de4877c11cb1609ca71a0bb20;hb=5ddfdb0abdb68ea85a8c55de9303963843d0be87#l468

Thanks for the response.
Based on the output I’m seeing, i.e., “Already on the latest version,” the third link with the code path
468 # Check the version of the local database

469 if db and t and db.created_at >= t:

470 log.info(“Already on the latest version”)

471 return

is what I’m hitting and I take it you’re suggesting just change that return on 471 to return 3? If that’s all it is, then yeah, that would get it to match the man page and solve my problem—and I think it would also add the meaningful signal that the man page suggests was intended. As I’m on a resource-constrained box, it would certainly be beneficial to not have to run the export if the db is up to date.

In normal practice, I’m not entirely sure how much this will matter since it appears (from an n=3) that the database version changes at roughly 04:30 GMT every day and thus it will be returning zero with the default systemd timer:

$ systemctl cat location-update.timer
# /usr/lib/systemd/system/location-update.timer
[Unit]
Description=Update the location database once a day

[Timer]
OnCalendar=daily
RandomizedDelaySec=24h

[Install]
WantedBy=timers.target

However, as I was trying to build and test my service unit I was hoping to use the return code as a gate for the ExecStartPost commands after the update:

$ systemctl cat location-update.service --no-pager
# /usr/lib/systemd/system/location-update.service
[Unit]
Description=Automatic Location Database Updater
Documentation=man:location(1) https://man-pages.ipfire.org/libloc/location.html
Requires=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/location update

# /etc/systemd/system/location-update.service.d/override.conf
[Service]
EnvironmentFile=/etc/location/blocked-asn.env
ExecStartPost=/usr/bin/location export --directory=/var/lib/location/nftables --format=nftables --family=ipv4 $BLOCKED_ASNs US
ExecStartPost=/usr/bin/location export --directory=/var/lib/location/nftables --format=nftables --family=ipv6 $BLOCKED_ASNs US
ExecStartPost=/usr/locals/bin/generate-asn-blocked-nft.sh

So I do think that return 3 has utility regardless. That said, I had been hoping not to need a helper script in my service unit, but since I now have one, I can just replace the ExecStart and read the STDOUT of /usr/bin/location update instead of using the return code if the decision is made to have the man file match the current output of location rather than vise-versa (though string matching is more fragile than a non-zero exit code). Saving the timestamp and location version output somewhere is also an option, but that seems even more epicyclic.

Thanks again for the response. If there’s a PR entered for this, I would appreciate it if you’d include it in this thread so I can subscribe.

It is confirmed by @ms that it should be return 3.

I will submit a patch for this later next week and will raise a bug report shortly as a reminder for myself.

https://bugzilla.ipfire.org/show_bug.cgi?id=14047