Maybe you specify the wront user or group in your systemd service.

Or another case, rare, that I’ve met in my work place: your application is executed by the forbidden uid / gid: 65535

So what you can do with your application that you can’t start/stop in a systemd service?

Just change the user uid (and gid if gid is also 65535), and apply the modification on your application files.

For instance here I’ll show what to do with this kind of problem for an Oracle database.

What is the cause of 65535 is forbidden by systemd

Note that Red Hat Enterprise Linux is able to handle a wider range of user and group IDs, as explained here: What are the maximum UID and GID values in Red Hat Enterprise Linux?. The 65535 ID limitation applies only to systemd units.

This issue will also reproduce if UID/GID is 0xFFFFFFFF which is 4294967295, because this special id is also also checked by systemd and is not allowed:

see this article from ReDHAT

How to solve it status=217/USER when uid or gid is 65535

An example with oracle database server executed as user oracle uid 65535 and group oinstall gid 65535

If you are in this case, it means that there was an error made when creating the oracle user, you should have avoir 65535.

What you can do know is to change the uid and gid by following these steps illustrated here:

[root@nicodevlog ~]# systemctl start dbora
[root@nicodevlog ~]# journalctl -u dbora
-- Logs begin at Wed 2022-09-07 21:50:40 CEST, end at Sun 2022-09-11 22:22:56 CEST. --
sept. 11 22:22:56 nicodevlog systemd[1]: Started The Oracle Database Service.
sept. 11 22:22:56 nicodevlog systemd[1]: dbora.service: Main process exited, code=exited, status=217/USER
sept. 11 22:22:56 nicodevlog systemd[1]: dbora.service: Failed with result 'exit-code'.
[root@nicodevlog ~]# cat /etc/systemd/system/dbora.service | grep User
User=oracle
[root@nicodevlog ~]# cat /etc/systemd/system/dbora.service | grep Group
Group=oinstall
[root@nicodevlog ~]# id oracle
uid=65535(oracle) gid=65535(oinstall) groupes=65535(oinstall),65541(racdba),65536(dba),65537(oper),65538(backupdba),65539(dgdba),65540(kmdba)

We can see uid and gid are equal to 65535. You have to find another number that is not already taken by a user or by a group:

[root@nicodevlog ~]# getent passwd 65542
[root@nicodevlog ~]# getent group 65542
[root@nicodevlog ~]#

65542 is free, we can use it to replace the uid of oracle, and the gid of oinstall.

Save the original files in case a problem happens:

cp --preserve /etc/passwd /etc/passwd.save
cp --preserve /etc/group /etc/group.save

/!\ Then it’s important to kill all processes that are executed as oracle or by a user that is inside oinstall group /!\

1/ SHUTDOWN IMMEDIATE the oracle database (or your application if it’s not oracle).

2/ Stop the listener: lsnrctl stop

3/ And then kill all the other processes concerned by uid 65535 (here oracle user with group oinstall).

[root@nicodevlog ~]# ps -ef | grep oracle
root       61430   61067  0 22:37 pts/1    00:00:00 grep --color=auto oracle
[root@nicodevlog ~]# ps -ef | grep oinstall
root       61432   61067  0 22:37 pts/1    00:00:00 grep --color=auto oinstall
[root@nicodevlog ~]# ps -ef | grep 65535
root       61434   61067  0 22:37 pts/1    00:00:00 grep --color=auto 65535

Above You can see there is no processes to be killed.

Now You change the gid of the group oinstall, and then the uid/gid of the oracle user.

[root@nicodevlog ~]# groupmod -g 65542 oinstall
[root@nicodevlog ~]# usermod -u 65542 -g 65542 oracle
[root@nicodevlog ~]# id oracle
uid=65542(oracle) gid=65542(oinstall) groupes=65542(oinstall),65541(racdba),65536(dba),65537(oper),65538(backupdba),65539(dgdba),65540(kmdba)

Now You have to chown -R oracle:oinstall all the files and directories of your application (ie oracle in this example). BUT before verify there is no setuid or setguid bits.

The octal value of setuid is 4.

The octal value of setguid is 2.

The octal value of the stiky bit is 1.

Now you have to search if these three bits are set on some files that are owned by uid 65535 because these will be affected by the chown -R oracle:oinstall command.
You can search the octal value 7 like this (it’s the sum of the octal value of these three bits):

[root@nicodevlog ~]# find / -uid 65535 -perm /7000 -ls
find: ‘/proc/61576/task/61576/fd/5’: Aucun fichier ou dossier de ce type
find: ‘/proc/61576/task/61576/fdinfo/5’: Aucun fichier ou dossier de ce type
find: ‘/proc/61576/fd/6’: Aucun fichier ou dossier de ce type
find: ‘/proc/61576/fdinfo/6’: Aucun fichier ou dossier de ce type
109052928      0 drwxrwxrwt   2  65535    65535           6 sept. 11 22:37 /var/tmp/.oracle
 68246188    212 -rwxr-s--x   1  65535    65535      214096 avril 20 16:54 /u01/app/oracle/product/19.3.0/dbhome_1/bin/extproc
 67109272 438028 -rwsr-s--x   1  65535    65535    448537456 mai  3 18:11 /u01/app/oracle/product/19.3.0/dbhome_1/bin/oracle
 42746822      0 drwxr-x--T   5  65535    65535           62 mai  3 18:00 /u01/app/oracle/product/19.3.0/dbhome_1/log
 50871801      0 drwxr-x--T   3  65535    65535           20 avril 20 17:15 /u01/app/oracle/product/19.3.0/dbhome_1/log/nicodevlog 
 58892950      0 drwxr-x--T   2  65535    65535           30 avril 20 17:15 /u01/app/oracle/product/19.3.0/dbhome_1/log/nicodevlog /client
109328472      0 drwxr-xr-t   3  65535    65535           20 mai  3 18:00 /u01/app/oracle/product/19.3.0/dbhome_1/log/nicodevlog 
  1138082      0 drwxr-xr-t   2  65535    65535          150 sept.  7 21:51 /u01/app/oracle/product/19.3.0/dbhome_1/log/nicodevlog /client
[root@nicodevlog ~]# find / -uid 65535 -perm /7000 -ls > /root/list_setuid_setgid_stickybit_65535.txt
find: ‘/proc/61593/task/61593/fd/5’: Aucun fichier ou dossier de ce type
find: ‘/proc/61593/task/61593/fdinfo/5’: Aucun fichier ou dossier de ce type
find: ‘/proc/61593/fd/6’: Aucun fichier ou dossier de ce type
find: ‘/proc/61593/fdinfo/6’: Aucun fichier ou dossier de ce type
[root@nicodevlog ~]#

The file list_setuid_setgid_stickybit_65535.txt now contains all the files that we should track after a chown command.

[root@nicodevlog ~]# chown -R oracle:oinstall /home/oracle
[root@nicodevlog ~]# chown -R oracle:oinstall /u01
[root@nicodevlog ~]# chown -R oracle:oinstall /u02
[root@nicodevlog ~]# chown -R oracle:oinstall /var/tmp/.oracle
[root@nicodevlog ~]#
[root@nicodevlog ~]# ls -la /u01/app/oracle/product/19.3.0/dbhome_1/bin/extproc
-rwxr-x--x. 1 oracle oinstall 214096 20 avril 16:54 /u01/app/oracle/product/19.3.0/dbhome_1/bin/extproc
[root@nicodevlog ~]# chmod 2751 /u01/app/oracle/product/19.3.0/dbhome_1/bin/extproc
[root@nicodevlog ~]# ls -la /u01/app/oracle/product/19.3.0/dbhome_1/bin/extproc
-rwxr-s--x. 1 oracle oinstall 214096 20 avril 16:54 /u01/app/oracle/product/19.3.0/dbhome_1/bin/extproc
[root@nicodevlog ~]#
[root@nicodevlog ~]# ls -la /u01/app/oracle/product/19.3.0/dbhome_1/bin/oracle
-rwxr-x--x. 1 oracle oinstall 448537456  3 mai   18:11 /u01/app/oracle/product/19.3.0/dbhome_1/bin/oracle
[root@nicodevlog ~]# chmod 6751 /u01/app/oracle/product/19.3.0/dbhome_1/bin/oracle
[root@nicodevlog ~]# ls -la /u01/app/oracle/product/19.3.0/dbhome_1/bin/oracle
-rwsr-s--x. 1 oracle oinstall 448537456  3 mai   18:11 /u01/app/oracle/product/19.3.0/dbhome_1/bin/oracle
[root@nicodevlog ~]#
[root@nicodevlog ~]#
[root@nicodevlog ~]# ls -la /var/tmp/
total 8
drwxrwxrwt.  7 root   root     4096  7 sept. 21:52 .
drwxr-xr-x. 21 root   root     4096  1 avril 12:38 ..
drwxrwxrwt.  2 oracle oinstall    6 11 sept. 22:37 .oracle

In fact you can see I didn’t track the sticky bit, because it’s not affected by the chown command as our chown command refers to uid and guid and not the sticky bit. I talked about the sticky bit only for information, but you don’t have to care about it.

Now we can try our systemd service, in this following example the dbora.service which can start the database needs to be tested by a reboot of linux because the dbora.service calls a script (dbstart) which only works well on reboot.
But in most of cases you can directly test and your service without linux reboot.

We reboot Linux. Now that linux system has rebooted we can verify that systemd service has correctly started at the linux boot:

[root@nicodevlog ~]# systemctl status dbora
● dbora.service - The Oracle Database Service
   Loaded: loaded (/etc/systemd/system/dbora.service; enabled; vendor preset: disabled)
   Active: active (exited) since Sun 2022-09-11 23:12:49 CEST; 644ms ago
  Process: 1215 ExecStart=/bin/bash -c source /home/oracle/.bash_profile && /home/oracle/scripts/start_all.sh (code=exited, status=0/SUCCESS)
 Main PID: 1215 (code=exited, status=0/SUCCESS)
    Tasks: 52 (limit: 75958)
   Memory: 4.7G
   CGroup: /system.slice/dbora.service
           ├─1360 /u01/app/oracle/product/19.3.0/dbhome_1/bin/tnslsnr LISTENER -inherit
           ├─2231 ora_pmon_orhus
           ├─2235 ora_clmn_orhus
           ├─2239 ora_psp0_orhus
           ├─2243 ora_vktm_orhus
.....
.....
[root@nicodevlog ~]# journalctl -u dbora
-- Logs begin at Sun 2022-09-11 23:12:04 CEST, end at Sun 2022-09-11 23:12:57 CEST. --
sept. 11 23:12:49 nicodevlog systemd[1]: Started The Oracle Database Service.
sept. 11 23:12:49 nicodevlog bash[1215]: The Oracle base remains unchanged with value /u01/app/oracle
sept. 11 23:12:50 nicodevlog bash[1215]: Processing Database instance "orhus": log file /u01/app/oracle/product/19.3.0/dbhome_1/rdbms/lo>

Our application started and we don’t have anymore the error code=exited, status=217/USER.

🙂