I'm starting a webserver as non-root using a systemd unit file.

I am getting listen tcp :80: bind: permission denied even though I already ran

setcap cap_net_bind_service=+ep

on the executable.

In an example unit file on the internet I found


to be used in the unit file. So I tried that out, and suddenly the application can bind port 80.

What does that tell me? setcap is old/deprecated/ignored? Only by systemd or by Linux in general?

  • setcapworks as if you were setting the SETUID bit on the file, that means that a regular use would gain the extra capabilities listed there, that can be necessary but not when starting a daemon
    – Bigon
    Dec 15, 2018 at 9:52

1 Answer 1


It's correct to say that in general systemd will not work with file capabilities managed with setcap and will require you to configure them as part of the service unit instead.

So it's not like setcap is completely deprecated... (There might be valid uses for it outside of services launched by systemd.) But it doesn't really work for systemd services, at least.

In fact, file capabilities (set by setcap) were always dubious and questionable, from the start... They require the use of "inheritable" capabilities, which were somewhat poorly conceived and had many shortcomings... The kernel feature of "ambient" capabilities was introduced to solve many of these issues and it's what newer systems are adopting (systemd included here, as you can see, you're setting AmbientCapabilities= for your service to manage to be able to bind to low ports.)

The topic of capabilities is fairly complex... For a perhaps gentler introduction to this issue, you might want to check "Inheriting capabilities" at LWN. For the full gory details (including some algebraic notation on the capability sets), refer to the capabilities(7) man page.

  • 1
    Why? CapabilityBoundingSet= : "If this option is not used, the capability bounding set is not modified on process execution, hence no limits on the capabilities of the process are enforced."
    – sourcejedi
    Dec 14, 2018 at 23:23
  • @sourcejedi I haven't checked this in a while... If I remember correctly, the issue is that SecureBits= lacks keep-caps, which means capability bounding set is preserved for root but then a transition to a non-root user will end up dropping them... (When I have some time I'll try to take a fresh look at this and add some more details to the answer... Though feel free to go ahead and do that if you feel like it too!)
    – filbranden
    Dec 14, 2018 at 23:41
  • setcap is not dubious. It replaces set-uid-root, as the only way to escalate privileges. With out it, you have to keep privileges high, so that you can pass them on. Both models have there place. Mar 4, 2020 at 7:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .